Skip to content
This repository was archived by the owner on Aug 2, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
3d92c93
swarm/storage: Simplify code, correct content hashing
nolash Jan 18, 2018
cf191d3
swarm/storage: Remove signatures from non-validated resources
nolash Jan 18, 2018
13543f4
swarm: Add base api for mutable resources
nolash Jan 18, 2018
81ec1f9
swarm/api: Add all lookup types + public getblock
nolash Jan 19, 2018
1bf4f4a
swarm/api: Add raw form to api+server WIP
nolash Jan 19, 2018
249e1a8
swarm, cmd/swarm, ethclient: Fullstack mut.rsrc. w api
nolash Jan 19, 2018
a16d0af
swarm/, cmd/swarm: Amend comments from @lmars PR 204
nolash Jan 21, 2018
11c3b4c
swarm/api: Add contenttype contingent resolve manifest -> rsrc
nolash Jan 22, 2018
80f539c
swarm/api: Rename Db -> Resource
nolash Jan 22, 2018
aff40c4
swarm/storage, ethclient: Move signature to end of chunk data
nolash Jan 22, 2018
703051b
swarm: Cleanup after rebase on swarm-mutableresources-extsign
nolash Jan 22, 2018
c2e0be6
swarm/storage, swarm/api: Change noparam fmt.Errorf -> errors.New
nolash Jan 22, 2018
400b7d6
swarm/api/http: Test result data
nolash Jan 22, 2018
0455925
swarm: Amend comments from @lmars PR 204 second review, part I
nolash Jan 22, 2018
a32681c
swarm/storage: Correct channel for waiting on chunk put
nolash Jan 23, 2018
94303aa
swarm/storage: Implement resourcehandler hashers as sync.Pool
nolash Jan 23, 2018
edacd4b
swarm/api: Remove faulty manifest handling + add rsrc create keycheck
nolash Jan 23, 2018
690522b
swarm/api: Amend @gbalint comments PR 204 + args dep test loglvl
nolash Jan 23, 2018
88ed2d4
swarm, ethclient: Add version test for http api
nolash Jan 23, 2018
4a7b5b8
swarm/api, swarm/storage: Delinting
nolash Jan 23, 2018
add8971
swarm/api, swarm/storage: Fullstack contexts
nolash Jan 24, 2018
8d7bf3f
swarm/fuse: Update swarm/api:Api.NewAPI constructor
nolash Jan 24, 2018
de74542
swarm: Add missing privatekey from swarm config w/o swap
nolash Jan 24, 2018
f38859d
swarm/storage: Delint
nolash Jan 25, 2018
ef5eeb6
swarm: Remove privkey log entry
nolash Jan 25, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/swarm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ func registerBzzService(bzzconfig *bzzapi.Config, ctx *cli.Context, stack *node.
}

// In production, mockStore must be always nil.
return swarm.NewSwarm(ctx, swapClient, ensClient, bzzconfig, bzzconfig.SwapEnabled, bzzconfig.SyncEnabled, bzzconfig.Cors, bzzconfig.PssEnabled, nil)
return swarm.NewSwarm(ctx, swapClient, ensClient, bzzconfig, nil)
}
//register within the ethereum node
if err := stack.Register(boot); err != nil {
Expand Down
60 changes: 55 additions & 5 deletions swarm/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package api

import (
"context"
"fmt"
"io"
"net/http"
Expand Down Expand Up @@ -46,15 +47,17 @@ on top of the dpa
it is the public interface of the dpa which is included in the ethereum stack
*/
type Api struct {
dpa *storage.DPA
dns Resolver
resource *storage.ResourceHandler
dpa *storage.DPA
dns Resolver
}

//the api constructor initialises
func NewApi(dpa *storage.DPA, dns Resolver) (self *Api) {
func NewApi(dpa *storage.DPA, dns Resolver, resourceHandler *storage.ResourceHandler) (self *Api) {
self = &Api{
dpa: dpa,
dns: dns,
dpa: dpa,
dns: dns,
resource: resourceHandler,
}
return
}
Expand Down Expand Up @@ -361,3 +364,50 @@ func (self *Api) BuildDirectoryTree(mhash string, nameresolver bool) (key storag
}
return key, manifestEntryMap, nil
}

// Look up mutable resource updates at specific periods and versions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's not call it Db anything please

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 221b084

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(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(ctx, name, period, version, true)
} else if period != 0 {
_, err = self.resource.LookupHistoricalByName(ctx, name, period, true)
} else {
_, err = self.resource.LookupLatestByName(ctx, name, true)
}
if err != nil {
return nil, nil, err
}
return self.resource.GetContent(name)
}

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
}
h := rsrc.NameHash()
return storage.Key(h[:]), nil
}

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
}

func (self *Api) ResourceHashSize() int {
return self.resource.HashSize()
}

func (self *Api) ResourceIsValidated() bool {
return self.resource.IsValidated()
}
2 changes: 1 addition & 1 deletion swarm/api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func testApi(t *testing.T, f func(*Api)) {
if err != nil {
return
}
api := NewApi(dpa, nil)
api := NewApi(dpa, nil, nil)
dpa.Start()
f(api)
dpa.Stop()
Expand Down
74 changes: 43 additions & 31 deletions swarm/api/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,24 @@ type Config struct {
*network.HiveParams
Swap *swap.SwapParams
//*network.SyncParams
Contract common.Address
EnsRoot common.Address
EnsApi string
Path string
ListenAddr string
Port string
PublicKey string
BzzKey string
NetworkId uint64
SwapEnabled bool
SyncEnabled bool
PssEnabled bool
SwapApi string
Cors string
BzzAccount string
BootNodes string
Contract common.Address
EnsRoot common.Address
EnsApi string
Path string
ListenAddr string
Port string
PublicKey string
BzzKey string
NetworkId uint64
SwapEnabled bool
SyncEnabled bool
PssEnabled bool
ResourceEnabled bool
SwapApi string
Cors string
BzzAccount string
BootNodes string
privateKey *ecdsa.PrivateKey
}

//create a default config with all parameters to set to defaults
Expand All @@ -72,18 +74,19 @@ func NewConfig() (self *Config) {
ChunkerParams: storage.NewChunkerParams(),
HiveParams: network.NewHiveParams(),
//SyncParams: network.NewDefaultSyncParams(),
Swap: swap.NewDefaultSwapParams(),
ListenAddr: DefaultHTTPListenAddr,
Port: DefaultHTTPPort,
Path: node.DefaultDataDir(),
EnsApi: node.DefaultIPCEndpoint("geth"),
EnsRoot: ens.TestNetAddress,
NetworkId: network.NetworkID,
SwapEnabled: false,
SyncEnabled: true,
PssEnabled: true,
SwapApi: "",
BootNodes: "",
Swap: swap.NewDefaultSwapParams(),
ListenAddr: DefaultHTTPListenAddr,
Port: DefaultHTTPPort,
Path: node.DefaultDataDir(),
EnsApi: node.DefaultIPCEndpoint("geth"),
EnsRoot: ens.TestNetAddress,
NetworkId: network.NetworkID,
SwapEnabled: false,
SyncEnabled: true,
PssEnabled: true,
ResourceEnabled: true,
SwapApi: "",
BootNodes: "",
}

return
Expand All @@ -108,8 +111,17 @@ func (self *Config) Init(prvKey *ecdsa.PrivateKey) {
self.PublicKey = pubkeyhex
self.BzzKey = keyhex

self.Swap.Init(self.Contract, prvKey)
//self.SyncParams.Init(self.Path)
//self.HiveParams.Init(self.Path)
if self.SwapEnabled {
self.Swap.Init(self.Contract, prvKey)
}
self.privateKey = prvKey
self.StoreParams.Init(self.Path)
}

func (self *Config) ShiftPrivateKey() (privKey *ecdsa.PrivateKey) {
if self.privateKey != nil {
privKey = self.privateKey
self.privateKey = nil
}
return privKey
}
9 changes: 1 addition & 8 deletions swarm/api/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,9 @@ func TestConfig(t *testing.T) {
if one.PublicKey == "" {
t.Fatal("Expected PublicKey to be set")
}

//the Init function should append subdirs to the given path
if one.Swap.PayProfile.Beneficiary == (common.Address{}) {
if one.Swap.PayProfile.Beneficiary == (common.Address{}) && one.SwapEnabled {
t.Fatal("Failed to correctly initialize SwapParams")
}

if one.HiveParams.MaxPeersPerRequest != 5 {
t.Fatal("Failed to correctly initialize HiveParams")
}

if one.StoreParams.ChunkDbPath == one.Path {
t.Fatal("Failed to correctly initialize StoreParams")
}
Expand Down
101 changes: 99 additions & 2 deletions swarm/api/http/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package http

import (
"archive/tar"
"bytes"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -290,6 +291,95 @@ func (s *Server) HandleDelete(w http.ResponseWriter, r *Request) {
fmt.Fprint(w, newKey)
}

func (s *Server) HandlePostResource(w http.ResponseWriter, r *Request) {
var outdata string
if r.uri.Path != "" {
frequency, err := strconv.ParseUint(r.uri.Path, 10, 64)
if err != nil {
s.BadRequest(w, r, fmt.Sprintf("Cannot parse frequency parameter: %v", err))
return
}
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
}
outdata = key.Hex()
}

data, err := ioutil.ReadAll(r.Body)
if err != nil {
s.Error(w, r, err)
return
}
_, _, _, 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
}

if outdata != "" {
w.Header().Add("Content-type", "text/plain")
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, outdata)
return
}
w.WriteHeader(http.StatusOK)
}

// Retrieve mutable resource updates:
// bzz-resource://<id> - get latest update
// bzz-resource://<id>/<n> - get latest update on period n
// bzz-resource://<id>/<n>/<m> - get update version m of period n
// <id> = ens name or hash
func (s *Server) HandleGetResource(w http.ResponseWriter, r *Request) {
s.handleGetResource(w, r, r.uri.Addr)
}

func (s *Server) handleGetResource(w http.ResponseWriter, r *Request, name string) {
var params []string
if len(r.uri.Path) > 0 {
params = strings.Split(r.uri.Path, "/")
}
var updateKey storage.Key
var period uint64
var version uint64
var data []byte
var err error
now := time.Now()
log.Debug("handlegetdb", "name", name)
switch len(params) {
case 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 {
break
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need for the err check just to break, the case will just break anyway.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lmars but the case branch continues and tries s.api.ResourceLookup with the version which it failed to parse

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is now misplaced, when I made it there was no code following this in the case.

period, err = strconv.ParseUint(params[0], 10, 32)
if err != nil {
break
}
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(r.Context(), name, uint32(period), uint32(version))
default:
s.BadRequest(w, r, "Invalid mutable resource request")
return
}
if err != nil {
s.Error(w, r, fmt.Errorf("Mutable resource lookup failed: %v", err))
return
}
log.Debug("Found update", "key", updateKey)
w.Header().Set("Content-Type", "application/octet-stream")
http.ServeContent(w, &r.Request, "", now, bytes.NewReader(data))
}

// HandleGet handles a GET request to
// - bzz-raw://<key> and responds with the raw content stored at the
// given storage key
Expand Down Expand Up @@ -335,7 +425,7 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
return api.SkipManifest
})
if entry == nil {
s.NotFound(w, r, fmt.Errorf("Manifest entry could not be loaded"))
s.NotFound(w, r, errors.New("Manifest entry could not be loaded"))
return
}
key = storage.Key(common.Hex2Bytes(entry.Hash))
Expand All @@ -357,7 +447,6 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
contentType = typ
}
w.Header().Set("Content-Type", contentType)

http.ServeContent(w, &r.Request, "", time.Now(), reader)
case r.uri.Hash():
w.Header().Set("Content-Type", "text/plain")
Expand Down Expand Up @@ -604,6 +693,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
case "POST":
if uri.Raw() || uri.DeprecatedRaw() {
s.HandlePostRaw(w, req)
} else if uri.Resource() {
s.HandlePostResource(w, req)
} else {
s.HandlePostFiles(w, req)
}
Expand All @@ -629,6 +720,12 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
s.HandleDelete(w, req)

case "GET":

if uri.Resource() {
s.HandleGetResource(w, req)
return
}

if uri.Raw() || uri.Hash() || uri.DeprecatedRaw() {
s.HandleGet(w, req)
return
Expand Down
Loading