mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 09:53:48 +00:00
swarm/storage, swarm/api, swarm/testutil: Explicit lookup limit params
This commit is contained in:
parent
8561834ded
commit
0d5b951614
5 changed files with 57 additions and 37 deletions
|
|
@ -579,17 +579,17 @@ func (self *Api) BuildDirectoryTree(mhash string, nameresolver bool) (key storag
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look up mutable resource updates at specific periods and versions
|
// Look up mutable resource updates at specific periods and versions
|
||||||
func (self *Api) ResourceLookup(ctx context.Context, name string, period uint32, version uint32, maxPeriod int) (storage.Key, []byte, error) {
|
func (self *Api) ResourceLookup(ctx context.Context, name string, period uint32, version uint32, maxLookup *storage.ResourceLookupParams) (storage.Key, []byte, error) {
|
||||||
var err error
|
var err error
|
||||||
if version != 0 {
|
if version != 0 {
|
||||||
if period == 0 {
|
if period == 0 {
|
||||||
return nil, nil, storage.NewResourceError(storage.ErrInvalidValue, "Period can't be 0")
|
return nil, nil, storage.NewResourceError(storage.ErrInvalidValue, "Period can't be 0")
|
||||||
}
|
}
|
||||||
_, err = self.resource.LookupVersionByName(ctx, name, period, version, true, maxPeriod)
|
_, err = self.resource.LookupVersionByName(ctx, name, period, version, true, maxLookup)
|
||||||
} else if period != 0 {
|
} else if period != 0 {
|
||||||
_, err = self.resource.LookupHistoricalByName(ctx, name, period, true, maxPeriod)
|
_, err = self.resource.LookupHistoricalByName(ctx, name, period, true, maxLookup)
|
||||||
} else {
|
} else {
|
||||||
_, err = self.resource.LookupLatestByName(ctx, name, true, maxPeriod)
|
_, err = self.resource.LookupLatestByName(ctx, name, true, maxLookup)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
|
|
||||||
|
|
@ -412,7 +412,7 @@ func (s *Server) handleGetResource(w http.ResponseWriter, r *Request, name strin
|
||||||
log.Debug("handlegetdb", "name", name, "ruid", r.ruid)
|
log.Debug("handlegetdb", "name", name, "ruid", r.ruid)
|
||||||
switch len(params) {
|
switch len(params) {
|
||||||
case 0:
|
case 0:
|
||||||
updateKey, data, err = s.api.ResourceLookup(r.Context(), name, 0, 0, 0)
|
updateKey, data, err = s.api.ResourceLookup(r.Context(), name, 0, 0, nil)
|
||||||
case 2:
|
case 2:
|
||||||
version, err = strconv.ParseUint(params[1], 10, 32)
|
version, err = strconv.ParseUint(params[1], 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -422,13 +422,13 @@ func (s *Server) handleGetResource(w http.ResponseWriter, r *Request, name strin
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
updateKey, data, err = s.api.ResourceLookup(r.Context(), name, uint32(period), uint32(version), 0)
|
updateKey, data, err = s.api.ResourceLookup(r.Context(), name, uint32(period), uint32(version), nil)
|
||||||
case 1:
|
case 1:
|
||||||
period, err = strconv.ParseUint(params[0], 10, 32)
|
period, err = strconv.ParseUint(params[0], 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
updateKey, data, err = s.api.ResourceLookup(r.Context(), name, uint32(period), uint32(version), 0)
|
updateKey, data, err = s.api.ResourceLookup(r.Context(), name, uint32(period), uint32(version), nil)
|
||||||
default:
|
default:
|
||||||
Respond(w, r, "invalid mutable resource request", http.StatusBadRequest)
|
Respond(w, r, "invalid mutable resource request", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,11 @@ func NewResourceError(code int, s string) error {
|
||||||
|
|
||||||
type Signature [signatureLength]byte
|
type Signature [signatureLength]byte
|
||||||
|
|
||||||
|
type ResourceLookupParams struct {
|
||||||
|
Limit bool
|
||||||
|
Max uint32
|
||||||
|
}
|
||||||
|
|
||||||
type SignFunc func(common.Hash) (Signature, error)
|
type SignFunc func(common.Hash) (Signature, error)
|
||||||
|
|
||||||
type nameHashFunc func(string) common.Hash
|
type nameHashFunc func(string) common.Hash
|
||||||
|
|
@ -164,16 +169,21 @@ type ResourceHandler struct {
|
||||||
resourceLock sync.RWMutex
|
resourceLock sync.RWMutex
|
||||||
nameHash nameHashFunc
|
nameHash nameHashFunc
|
||||||
storeTimeout time.Duration
|
storeTimeout time.Duration
|
||||||
queryMaxPeriods uint
|
queryMaxPeriods *ResourceLookupParams
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResourceHandlerParams struct {
|
type ResourceHandlerParams struct {
|
||||||
Validator ResourceValidator
|
Validator ResourceValidator
|
||||||
QueryMaxPeriods uint
|
QueryMaxPeriods *ResourceLookupParams
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create or open resource update chunk store
|
// Create or open resource update chunk store
|
||||||
func NewResourceHandler(hasher SwarmHasher, chunkStore ChunkStore, ethClient headerGetter, params *ResourceHandlerParams) (*ResourceHandler, error) {
|
func NewResourceHandler(hasher SwarmHasher, chunkStore ChunkStore, ethClient headerGetter, params *ResourceHandlerParams) (*ResourceHandler, error) {
|
||||||
|
if params.QueryMaxPeriods == nil {
|
||||||
|
params.QueryMaxPeriods = &ResourceLookupParams{
|
||||||
|
Limit: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
rh := &ResourceHandler{
|
rh := &ResourceHandler{
|
||||||
ChunkStore: chunkStore,
|
ChunkStore: chunkStore,
|
||||||
ethClient: ethClient,
|
ethClient: ethClient,
|
||||||
|
|
@ -330,16 +340,16 @@ func (self *ResourceHandler) NewResource(ctx context.Context, name string, frequ
|
||||||
// If maxPeriod is -1, the default QueryMaxPeriod from ResourceHandlerParams will be used
|
// If maxPeriod is -1, the default QueryMaxPeriod from ResourceHandlerParams will be used
|
||||||
// if maxPeriod is 0, there will be no limit on period hops
|
// if maxPeriod is 0, there will be no limit on period hops
|
||||||
// if maxPeriod > 0, the given value will be the limit of period hops
|
// if maxPeriod > 0, the given value will be the limit of period hops
|
||||||
func (self *ResourceHandler) LookupVersionByName(ctx context.Context, name string, period uint32, version uint32, refresh bool, maxPeriod int) (*resource, error) {
|
func (self *ResourceHandler) LookupVersionByName(ctx context.Context, name string, period uint32, version uint32, refresh bool, maxLookup *ResourceLookupParams) (*resource, error) {
|
||||||
return self.LookupVersion(ctx, self.nameHash(name), name, period, version, refresh, maxPeriod)
|
return self.LookupVersion(ctx, self.nameHash(name), name, period, version, refresh, maxLookup)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ResourceHandler) LookupVersion(ctx context.Context, nameHash common.Hash, name string, period uint32, version uint32, refresh bool, maxPeriod int) (*resource, error) {
|
func (self *ResourceHandler) LookupVersion(ctx context.Context, nameHash common.Hash, name string, period uint32, version uint32, refresh bool, maxLookup *ResourceLookupParams) (*resource, error) {
|
||||||
rsrc, err := self.loadResource(nameHash, name, refresh)
|
rsrc, err := self.loadResource(nameHash, name, refresh)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return self.lookup(rsrc, period, version, refresh, maxPeriod)
|
return self.lookup(rsrc, period, version, refresh, maxLookup)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves the latest version of the resource update identified by `name`
|
// Retrieves the latest version of the resource update identified by `name`
|
||||||
|
|
@ -350,16 +360,16 @@ func (self *ResourceHandler) LookupVersion(ctx context.Context, nameHash common.
|
||||||
// and returned.
|
// and returned.
|
||||||
//
|
//
|
||||||
// See also (*ResourceHandler).LookupVersion
|
// See also (*ResourceHandler).LookupVersion
|
||||||
func (self *ResourceHandler) LookupHistoricalByName(ctx context.Context, name string, period uint32, refresh bool, maxPeriod int) (*resource, error) {
|
func (self *ResourceHandler) LookupHistoricalByName(ctx context.Context, name string, period uint32, refresh bool, maxLookup *ResourceLookupParams) (*resource, error) {
|
||||||
return self.LookupHistorical(ctx, self.nameHash(name), name, period, refresh, maxPeriod)
|
return self.LookupHistorical(ctx, self.nameHash(name), name, period, refresh, maxLookup)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ResourceHandler) LookupHistorical(ctx context.Context, nameHash common.Hash, name string, period uint32, refresh bool, maxPeriod int) (*resource, error) {
|
func (self *ResourceHandler) LookupHistorical(ctx context.Context, nameHash common.Hash, name string, period uint32, refresh bool, maxLookup *ResourceLookupParams) (*resource, error) {
|
||||||
rsrc, err := self.loadResource(nameHash, name, refresh)
|
rsrc, err := self.loadResource(nameHash, name, refresh)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return self.lookup(rsrc, period, 0, refresh, maxPeriod)
|
return self.lookup(rsrc, period, 0, refresh, maxLookup)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieves the latest version of the resource update identified by `name`
|
// Retrieves the latest version of the resource update identified by `name`
|
||||||
|
|
@ -372,11 +382,11 @@ func (self *ResourceHandler) LookupHistorical(ctx context.Context, nameHash comm
|
||||||
// Version iteration is done as in (*ResourceHandler).LookupHistorical
|
// Version iteration is done as in (*ResourceHandler).LookupHistorical
|
||||||
//
|
//
|
||||||
// See also (*ResourceHandler).LookupHistorical
|
// See also (*ResourceHandler).LookupHistorical
|
||||||
func (self *ResourceHandler) LookupLatestByName(ctx context.Context, name string, refresh bool, maxPeriod int) (*resource, error) {
|
func (self *ResourceHandler) LookupLatestByName(ctx context.Context, name string, refresh bool, maxLookup *ResourceLookupParams) (*resource, error) {
|
||||||
return self.LookupLatest(ctx, self.nameHash(name), name, refresh, maxPeriod)
|
return self.LookupLatest(ctx, self.nameHash(name), name, refresh, maxLookup)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ResourceHandler) LookupLatest(ctx context.Context, nameHash common.Hash, name string, refresh bool, maxPeriod int) (*resource, error) {
|
func (self *ResourceHandler) LookupLatest(ctx context.Context, nameHash common.Hash, name string, refresh bool, maxLookup *ResourceLookupParams) (*resource, error) {
|
||||||
|
|
||||||
// get our blockheight at this time and the next block of the update period
|
// get our blockheight at this time and the next block of the update period
|
||||||
rsrc, err := self.loadResource(nameHash, name, refresh)
|
rsrc, err := self.loadResource(nameHash, name, refresh)
|
||||||
|
|
@ -388,11 +398,11 @@ func (self *ResourceHandler) LookupLatest(ctx context.Context, nameHash common.H
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
nextperiod := getNextPeriod(rsrc.startBlock, currentblock, rsrc.frequency)
|
nextperiod := getNextPeriod(rsrc.startBlock, currentblock, rsrc.frequency)
|
||||||
return self.lookup(rsrc, nextperiod, 0, refresh, maxPeriod)
|
return self.lookup(rsrc, nextperiod, 0, refresh, maxLookup)
|
||||||
}
|
}
|
||||||
|
|
||||||
// base code for public lookup methods
|
// base code for public lookup methods
|
||||||
func (self *ResourceHandler) lookup(rsrc *resource, period uint32, version uint32, refresh bool, maxPeriod int) (*resource, error) {
|
func (self *ResourceHandler) lookup(rsrc *resource, period uint32, version uint32, refresh bool, maxLookup *ResourceLookupParams) (*resource, error) {
|
||||||
|
|
||||||
if period == 0 {
|
if period == 0 {
|
||||||
return nil, NewResourceError(ErrInvalidValue, "period must be >0")
|
return nil, NewResourceError(ErrInvalidValue, "period must be >0")
|
||||||
|
|
@ -407,13 +417,13 @@ func (self *ResourceHandler) lookup(rsrc *resource, period uint32, version uint3
|
||||||
version = 1
|
version = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
hops := 0
|
var hops uint32
|
||||||
if maxPeriod < 0 {
|
if maxLookup == nil {
|
||||||
maxPeriod = int(self.queryMaxPeriods)
|
maxLookup = self.queryMaxPeriods
|
||||||
}
|
}
|
||||||
for period > 0 {
|
for period > 0 {
|
||||||
if hops > maxPeriod && maxPeriod > 0 {
|
if maxLookup.Limit && hops > maxLookup.Max {
|
||||||
return nil, NewResourceError(ErrPeriodDepth, fmt.Sprintf("Lookup exceeded max period hops (%d)", maxPeriod))
|
return nil, NewResourceError(ErrPeriodDepth, fmt.Sprintf("Lookup exceeded max period hops (%d)", maxLookup.Max))
|
||||||
}
|
}
|
||||||
key := self.resourceHash(period, version, rsrc.nameHash)
|
key := self.resourceHash(period, version, rsrc.nameHash)
|
||||||
chunk, err := self.Get(key)
|
chunk, err := self.Get(key)
|
||||||
|
|
@ -883,7 +893,7 @@ func isMultihash(data []byte) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this should not be part of production code, but currently swarm/testutil/http.go needs it
|
// TODO: this should not be part of production code, but currently swarm/testutil/http.go needs it
|
||||||
func NewTestResourceHandler(datadir string, ethClient headerGetter, validator ResourceValidator, maxPeriod uint) (*ResourceHandler, error) {
|
func NewTestResourceHandler(datadir string, ethClient headerGetter, validator ResourceValidator, maxLimit *ResourceLookupParams) (*ResourceHandler, error) {
|
||||||
path := filepath.Join(datadir, DbDirName)
|
path := filepath.Join(datadir, DbDirName)
|
||||||
basekey := make([]byte, 32)
|
basekey := make([]byte, 32)
|
||||||
hasher := MakeHashFunc(SHA3Hash)
|
hasher := MakeHashFunc(SHA3Hash)
|
||||||
|
|
@ -897,9 +907,14 @@ func NewTestResourceHandler(datadir string, ethClient headerGetter, validator Re
|
||||||
DbStore: dbStore,
|
DbStore: dbStore,
|
||||||
}
|
}
|
||||||
resourceChunkStore := NewResourceChunkStore(localStore, nil)
|
resourceChunkStore := NewResourceChunkStore(localStore, nil)
|
||||||
|
if maxLimit == nil {
|
||||||
|
maxLimit = &ResourceLookupParams{
|
||||||
|
Limit: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
params := &ResourceHandlerParams{
|
params := &ResourceHandlerParams{
|
||||||
Validator: validator,
|
Validator: validator,
|
||||||
QueryMaxPeriods: maxPeriod,
|
QueryMaxPeriods: maxLimit,
|
||||||
}
|
}
|
||||||
return NewResourceHandler(hasher, resourceChunkStore, ethClient, params)
|
return NewResourceHandler(hasher, resourceChunkStore, ethClient, params)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ var (
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
var err error
|
var err error
|
||||||
//loglevel := flag.Int("loglevel", 3, "loglevel")
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
log.Root().SetHandler(log.CallerFileHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(os.Stderr, log.TerminalFormat(true)))))
|
log.Root().SetHandler(log.CallerFileHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(os.Stderr, log.TerminalFormat(true)))))
|
||||||
safeName, err = ToSafeName(domainName)
|
safeName, err = ToSafeName(domainName)
|
||||||
|
|
@ -220,8 +219,14 @@ func TestResourceHandler(t *testing.T) {
|
||||||
// it will match on second iteration startblocknumber + (resourceFrequency * 3)
|
// it will match on second iteration startblocknumber + (resourceFrequency * 3)
|
||||||
fwdBlocks(int(resourceFrequency*2)-1, backend)
|
fwdBlocks(int(resourceFrequency*2)-1, backend)
|
||||||
|
|
||||||
rh2, err := NewTestResourceHandler(datadir, rh.ethClient, nil, 0)
|
lookupParams := &ResourceLookupParams{
|
||||||
_, err = rh2.LookupLatestByName(ctx, safeName, true, -1)
|
Limit: false,
|
||||||
|
}
|
||||||
|
rh2, err := NewTestResourceHandler(datadir, rh.ethClient, nil, lookupParams)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = rh2.LookupLatestByName(ctx, safeName, true, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -239,7 +244,7 @@ func TestResourceHandler(t *testing.T) {
|
||||||
log.Debug("Latest lookup", "period", rh2.resources[safeName].lastPeriod, "version", rh2.resources[safeName].version, "data", rh2.resources[safeName].data)
|
log.Debug("Latest lookup", "period", rh2.resources[safeName].lastPeriod, "version", rh2.resources[safeName].version, "data", rh2.resources[safeName].data)
|
||||||
|
|
||||||
// specific block, latest version
|
// specific block, latest version
|
||||||
rsrc, err := rh2.LookupHistoricalByName(ctx, safeName, 3, true, 0)
|
rsrc, err := rh2.LookupHistoricalByName(ctx, safeName, 3, true, lookupParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -250,7 +255,7 @@ func TestResourceHandler(t *testing.T) {
|
||||||
log.Debug("Historical lookup", "period", rh2.resources[safeName].lastPeriod, "version", rh2.resources[safeName].version, "data", rh2.resources[safeName].data)
|
log.Debug("Historical lookup", "period", rh2.resources[safeName].lastPeriod, "version", rh2.resources[safeName].version, "data", rh2.resources[safeName].data)
|
||||||
|
|
||||||
// specific block, specific version
|
// specific block, specific version
|
||||||
rsrc, err = rh2.LookupVersionByName(ctx, safeName, 3, 1, true, 0)
|
rsrc, err = rh2.LookupVersionByName(ctx, safeName, 3, 1, true, lookupParams)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -348,7 +353,7 @@ func TestResourceMultihash(t *testing.T) {
|
||||||
rh.Close()
|
rh.Close()
|
||||||
|
|
||||||
// test with signed data
|
// test with signed data
|
||||||
rh2, err := NewTestResourceHandler(datadir, rh.ethClient, validator, 0)
|
rh2, err := NewTestResourceHandler(datadir, rh.ethClient, validator, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -479,7 +484,7 @@ func setupTest(backend headerGetter, validator ResourceValidator) (rh *ResourceH
|
||||||
os.RemoveAll(datadir)
|
os.RemoveAll(datadir)
|
||||||
}
|
}
|
||||||
|
|
||||||
rh, err = NewTestResourceHandler(datadir, backend, validator, 0)
|
rh, err = NewTestResourceHandler(datadir, backend, validator, &ResourceLookupParams{Limit: false})
|
||||||
return rh, datadir, signer, cleanF, nil
|
return rh, datadir, signer, cleanF, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ func NewTestSwarmServer(t *testing.T) *TestSwarmServer {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rh, err := storage.NewTestResourceHandler(resourceDir, &fakeBackend{}, nil, 0)
|
rh, err := storage.NewTestResourceHandler(resourceDir, &fakeBackend{}, nil, &storage.ResourceLookupParams{Limit: false})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue