mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 17:33:47 +00:00
swarm/api, swarm/storage: Fullstack contexts
This commit is contained in:
parent
4a7b5b862a
commit
add8971467
4 changed files with 45 additions and 48 deletions
|
|
@ -17,6 +17,7 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
|
@ -365,21 +366,21 @@ func (self *Api) BuildDirectoryTree(mhash string, nameresolver bool) (key storag
|
|||
}
|
||||
|
||||
// Look up mutable resource updates at specific periods and versions
|
||||
func (self *Api) ResourceLookup(name string, period uint32, version uint32) (storage.Key, []byte, error) {
|
||||
func (self *Api) ResourceLookup(ctx context.Context, name string, period uint32, version uint32) (storage.Key, []byte, error) {
|
||||
var err error
|
||||
if version != 0 {
|
||||
if period == 0 {
|
||||
currentblocknumber, err := self.resource.GetBlock()
|
||||
currentblocknumber, err := self.resource.GetBlock(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Could not determine latest block: %v", err)
|
||||
}
|
||||
period = self.resource.BlockToPeriod(name, currentblocknumber)
|
||||
}
|
||||
_, err = self.resource.LookupVersionByName(name, period, version, true)
|
||||
_, err = self.resource.LookupVersionByName(ctx, name, period, version, true)
|
||||
} else if period != 0 {
|
||||
_, err = self.resource.LookupHistoricalByName(name, period, true)
|
||||
_, err = self.resource.LookupHistoricalByName(ctx, name, period, true)
|
||||
} else {
|
||||
_, err = self.resource.LookupLatestByName(name, true)
|
||||
_, err = self.resource.LookupLatestByName(ctx, name, true)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
|
@ -387,8 +388,8 @@ func (self *Api) ResourceLookup(name string, period uint32, version uint32) (sto
|
|||
return self.resource.GetContent(name)
|
||||
}
|
||||
|
||||
func (self *Api) ResourceCreate(name string, frequency uint64) (storage.Key, error) {
|
||||
rsrc, err := self.resource.NewResource(name, frequency)
|
||||
func (self *Api) ResourceCreate(ctx context.Context, name string, frequency uint64) (storage.Key, error) {
|
||||
rsrc, err := self.resource.NewResource(ctx, name, frequency)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -396,8 +397,8 @@ func (self *Api) ResourceCreate(name string, frequency uint64) (storage.Key, err
|
|||
return storage.Key(h[:]), nil
|
||||
}
|
||||
|
||||
func (self *Api) ResourceUpdate(name string, data []byte) (storage.Key, uint32, uint32, error) {
|
||||
key, err := self.resource.Update(name, data)
|
||||
func (self *Api) ResourceUpdate(ctx context.Context, name string, data []byte) (storage.Key, uint32, uint32, error) {
|
||||
key, err := self.resource.Update(ctx, name, data)
|
||||
period, _ := self.resource.GetLastPeriod(name)
|
||||
version, _ := self.resource.GetVersion(name)
|
||||
return key, period, version, err
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ func (s *Server) HandlePostResource(w http.ResponseWriter, r *Request) {
|
|||
s.BadRequest(w, r, fmt.Sprintf("Cannot parse frequency parameter: %v", err))
|
||||
return
|
||||
}
|
||||
key, err := s.api.ResourceCreate(r.uri.Addr, frequency)
|
||||
key, err := s.api.ResourceCreate(r.Context(), r.uri.Addr, frequency)
|
||||
if err != nil {
|
||||
s.Error(w, r, fmt.Errorf("Resource creation failed: %v", err))
|
||||
return
|
||||
|
|
@ -312,7 +312,7 @@ func (s *Server) HandlePostResource(w http.ResponseWriter, r *Request) {
|
|||
s.Error(w, r, err)
|
||||
return
|
||||
}
|
||||
_, _, _, err = s.api.ResourceUpdate(r.uri.Addr, data)
|
||||
_, _, _, err = s.api.ResourceUpdate(r.Context(), r.uri.Addr, data)
|
||||
if err != nil {
|
||||
s.Error(w, r, fmt.Errorf("Update resource failed: %v", err))
|
||||
return
|
||||
|
|
@ -350,7 +350,7 @@ func (s *Server) handleGetResource(w http.ResponseWriter, r *Request, name strin
|
|||
log.Debug("handlegetdb", "name", name)
|
||||
switch len(params) {
|
||||
case 0:
|
||||
updateKey, data, err = s.api.ResourceLookup(name, 0, 0)
|
||||
updateKey, data, err = s.api.ResourceLookup(r.Context(), name, 0, 0)
|
||||
case 2:
|
||||
version, err = strconv.ParseUint(params[1], 10, 32)
|
||||
if err != nil {
|
||||
|
|
@ -360,13 +360,13 @@ func (s *Server) handleGetResource(w http.ResponseWriter, r *Request, name strin
|
|||
if err != nil {
|
||||
break
|
||||
}
|
||||
updateKey, data, err = s.api.ResourceLookup(name, uint32(period), uint32(version))
|
||||
updateKey, data, err = s.api.ResourceLookup(r.Context(), name, uint32(period), uint32(version))
|
||||
case 1:
|
||||
period, err = strconv.ParseUint(params[0], 10, 32)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
updateKey, data, err = s.api.ResourceLookup(name, uint32(period), uint32(version))
|
||||
updateKey, data, err = s.api.ResourceLookup(r.Context(), name, uint32(period), uint32(version))
|
||||
default:
|
||||
s.BadRequest(w, r, "Invalid mutable resource request")
|
||||
return
|
||||
|
|
|
|||
|
|
@ -130,8 +130,6 @@ type ethApi interface {
|
|||
// TODO: Include modtime in chunk data + signature
|
||||
type ResourceHandler struct {
|
||||
ChunkStore
|
||||
ctx context.Context // base for new contexts passed to storage layer and ethapi, to ensure teardown when Close() is called
|
||||
cancelFunc func()
|
||||
validator ResourceValidator
|
||||
ethClient ethApi
|
||||
resources map[string]*resource
|
||||
|
|
@ -158,15 +156,12 @@ func NewResourceHandler(datadir string, cloudStore CloudStore, ethClient ethApi,
|
|||
DbStore: dbStore,
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
rh := &ResourceHandler{
|
||||
ChunkStore: newResourceChunkStore(path, hashfunc, localStore, cloudStore),
|
||||
ethClient: ethClient,
|
||||
resources: make(map[string]*resource),
|
||||
validator: validator,
|
||||
storeTimeout: defaultStoreTimeout,
|
||||
ctx: ctx,
|
||||
cancelFunc: cancel,
|
||||
hashPool: sync.Pool{
|
||||
New: func() interface{} {
|
||||
return MakeHashFunc(SHA3Hash)()
|
||||
|
|
@ -241,7 +236,7 @@ func (self *ResourceHandler) chunkSize() int64 {
|
|||
// The signature data should match the hash of the idna-converted name by the validator's namehash function, NOT the raw name bytes.
|
||||
//
|
||||
// The start block of the resource update will be the actual current block height of the connected network.
|
||||
func (self *ResourceHandler) NewResource(name string, frequency uint64) (*resource, error) {
|
||||
func (self *ResourceHandler) NewResource(ctx context.Context, name string, frequency uint64) (*resource, error) {
|
||||
|
||||
// frequency 0 is invalid
|
||||
if frequency == 0 {
|
||||
|
|
@ -272,7 +267,7 @@ func (self *ResourceHandler) NewResource(name string, frequency uint64) (*resour
|
|||
}
|
||||
|
||||
// get our blockheight at this time
|
||||
currentblock, err := self.GetBlock()
|
||||
currentblock, err := self.GetBlock(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -312,11 +307,11 @@ func (self *ResourceHandler) NewResource(name string, frequency uint64) (*resour
|
|||
// update root data was retrieved externally, it typically doesn't)
|
||||
//
|
||||
//
|
||||
func (self *ResourceHandler) LookupVersionByName(name string, period uint32, version uint32, refresh bool) (*resource, error) {
|
||||
return self.LookupVersion(self.nameHash(name), name, period, version, refresh)
|
||||
func (self *ResourceHandler) LookupVersionByName(ctx context.Context, name string, period uint32, version uint32, refresh bool) (*resource, error) {
|
||||
return self.LookupVersion(ctx, self.nameHash(name), name, period, version, refresh)
|
||||
}
|
||||
|
||||
func (self *ResourceHandler) LookupVersion(nameHash common.Hash, name string, period uint32, version uint32, refresh bool) (*resource, error) {
|
||||
func (self *ResourceHandler) LookupVersion(ctx context.Context, nameHash common.Hash, name string, period uint32, version uint32, refresh bool) (*resource, error) {
|
||||
rsrc, err := self.loadResource(nameHash, name, refresh)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -332,11 +327,11 @@ func (self *ResourceHandler) LookupVersion(nameHash common.Hash, name string, pe
|
|||
// and returned.
|
||||
//
|
||||
// See also (*ResourceHandler).LookupVersion
|
||||
func (self *ResourceHandler) LookupHistoricalByName(name string, period uint32, refresh bool) (*resource, error) {
|
||||
return self.LookupHistorical(self.nameHash(name), name, period, refresh)
|
||||
func (self *ResourceHandler) LookupHistoricalByName(ctx context.Context, name string, period uint32, refresh bool) (*resource, error) {
|
||||
return self.LookupHistorical(ctx, self.nameHash(name), name, period, refresh)
|
||||
}
|
||||
|
||||
func (self *ResourceHandler) LookupHistorical(nameHash common.Hash, name string, period uint32, refresh bool) (*resource, error) {
|
||||
func (self *ResourceHandler) LookupHistorical(ctx context.Context, nameHash common.Hash, name string, period uint32, refresh bool) (*resource, error) {
|
||||
rsrc, err := self.loadResource(nameHash, name, refresh)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -354,18 +349,18 @@ func (self *ResourceHandler) LookupHistorical(nameHash common.Hash, name string,
|
|||
// Version iteration is done as in (*ResourceHandler).LookupHistorical
|
||||
//
|
||||
// See also (*ResourceHandler).LookupHistorical
|
||||
func (self *ResourceHandler) LookupLatestByName(name string, refresh bool) (*resource, error) {
|
||||
return self.LookupLatest(self.nameHash(name), name, refresh)
|
||||
func (self *ResourceHandler) LookupLatestByName(ctx context.Context, name string, refresh bool) (*resource, error) {
|
||||
return self.LookupLatest(ctx, self.nameHash(name), name, refresh)
|
||||
}
|
||||
|
||||
func (self *ResourceHandler) LookupLatest(nameHash common.Hash, name string, refresh bool) (*resource, error) {
|
||||
func (self *ResourceHandler) LookupLatest(ctx context.Context, nameHash common.Hash, name string, refresh bool) (*resource, error) {
|
||||
|
||||
// get our blockheight at this time and the next block of the update period
|
||||
rsrc, err := self.loadResource(nameHash, name, refresh)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currentblock, err := self.GetBlock()
|
||||
currentblock, err := self.GetBlock(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -532,7 +527,7 @@ func (self *ResourceHandler) parseUpdate(chunkdata []byte) (*Signature, uint32,
|
|||
// It is the caller's responsibility to make sure that this data is not stale.
|
||||
//
|
||||
// A resource update cannot span chunks, and thus has max length 4096
|
||||
func (self *ResourceHandler) Update(name string, data []byte) (Key, error) {
|
||||
func (self *ResourceHandler) Update(ctx context.Context, name string, data []byte) (Key, error) {
|
||||
|
||||
var signaturelength int
|
||||
if self.validator != nil {
|
||||
|
|
@ -555,7 +550,7 @@ func (self *ResourceHandler) Update(name string, data []byte) (Key, error) {
|
|||
}
|
||||
|
||||
// get our blockheight at this time and the next block of the update period
|
||||
currentblock, err := self.GetBlock()
|
||||
currentblock, err := self.GetBlock(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -620,13 +615,10 @@ func (self *ResourceHandler) Update(name string, data []byte) (Key, error) {
|
|||
// Closes the datastore.
|
||||
// Always call this at shutdown to avoid data corruption.
|
||||
func (self *ResourceHandler) Close() {
|
||||
self.cancelFunc()
|
||||
self.ChunkStore.Close()
|
||||
}
|
||||
|
||||
func (self *ResourceHandler) GetBlock() (uint64, error) {
|
||||
ctx, cancel := context.WithCancel(self.ctx)
|
||||
defer cancel()
|
||||
func (self *ResourceHandler) GetBlock(ctx context.Context) (uint64, error) {
|
||||
blockheader, err := self.ethClient.HeaderByNumber(ctx, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
|
|
|||
|
|
@ -157,7 +157,9 @@ func TestResourceHandler(t *testing.T) {
|
|||
defer teardownTest()
|
||||
|
||||
// create a new resource
|
||||
_, err = rh.NewResource(safeName, resourceFrequency)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
_, err = rh.NewResource(ctx, safeName, resourceFrequency)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -183,7 +185,7 @@ func TestResourceHandler(t *testing.T) {
|
|||
resourcekey := make(map[string]Key)
|
||||
fwdBlocks(int(resourceFrequency/2), backend)
|
||||
data := []byte("blinky")
|
||||
resourcekey["blinky"], err = rh.Update(safeName, data)
|
||||
resourcekey["blinky"], err = rh.Update(ctx, safeName, data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -191,7 +193,7 @@ func TestResourceHandler(t *testing.T) {
|
|||
// update on first period
|
||||
fwdBlocks(int(resourceFrequency/2), backend)
|
||||
data = []byte("pinky")
|
||||
resourcekey["pinky"], err = rh.Update(safeName, data)
|
||||
resourcekey["pinky"], err = rh.Update(ctx, safeName, data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -199,7 +201,7 @@ func TestResourceHandler(t *testing.T) {
|
|||
// update on second period
|
||||
fwdBlocks(int(resourceFrequency), backend)
|
||||
data = []byte("inky")
|
||||
resourcekey["inky"], err = rh.Update(safeName, data)
|
||||
resourcekey["inky"], err = rh.Update(ctx, safeName, data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -207,7 +209,7 @@ func TestResourceHandler(t *testing.T) {
|
|||
// update just after second period
|
||||
fwdBlocks(1, backend)
|
||||
data = []byte("clyde")
|
||||
resourcekey["clyde"], err = rh.Update(safeName, data)
|
||||
resourcekey["clyde"], err = rh.Update(ctx, safeName, data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -219,7 +221,7 @@ func TestResourceHandler(t *testing.T) {
|
|||
fwdBlocks(int(resourceFrequency*2)-1, backend)
|
||||
|
||||
rh2, err := NewResourceHandler(datadir, &testCloudStore{}, rh.ethClient, nil)
|
||||
_, err = rh2.LookupLatestByName(safeName, true)
|
||||
_, err = rh2.LookupLatestByName(ctx, safeName, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -237,7 +239,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)
|
||||
|
||||
// specific block, latest version
|
||||
rsrc, err := rh2.LookupHistoricalByName(safeName, 3, true)
|
||||
rsrc, err := rh2.LookupHistoricalByName(ctx, safeName, 3, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -248,7 +250,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)
|
||||
|
||||
// specific block, specific version
|
||||
rsrc, err = rh2.LookupVersionByName(safeName, 3, 1, true)
|
||||
rsrc, err = rh2.LookupVersionByName(ctx, safeName, 3, 1, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -293,14 +295,16 @@ func TestResourceENSOwner(t *testing.T) {
|
|||
defer teardownTest()
|
||||
|
||||
// create new resource when we are owner = ok
|
||||
_, err = rh.NewResource(safeName, resourceFrequency)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
_, err = rh.NewResource(ctx, safeName, resourceFrequency)
|
||||
if err != nil {
|
||||
t.Fatalf("Create resource fail: %v", err)
|
||||
}
|
||||
|
||||
data := []byte("foo")
|
||||
// update resource when we are owner = ok
|
||||
_, err = rh.Update(safeName, data)
|
||||
_, err = rh.Update(ctx, safeName, data)
|
||||
if err != nil {
|
||||
t.Fatalf("Update resource fail: %v", err)
|
||||
}
|
||||
|
|
@ -311,7 +315,7 @@ func TestResourceENSOwner(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
rh.validator.(*ENSValidator).signFunc = signertwo.signContent
|
||||
_, err = rh.Update(safeName, data)
|
||||
_, err = rh.Update(ctx, safeName, data)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected resource update fail due to owner mismatch")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue