swarm/, cmd/swarm: Amend comments from @lmars PR 204

This commit is contained in:
lash 2018-01-21 03:13:52 +01:00
parent 249e1a8aaa
commit a16d0af41d
11 changed files with 166 additions and 217 deletions

View file

@ -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, bzzconfig.ResourceEnabled, nil)
return swarm.NewSwarm(ctx, swapClient, ensClient, bzzconfig, nil)
}
//register within the ethereum node
if err := stack.Register(boot); err != nil {

View file

@ -23,7 +23,6 @@ import (
"errors"
"fmt"
"math/big"
"strconv"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
@ -77,13 +76,19 @@ type rpcBlock struct {
UncleHashes []common.Hash `json:"uncles"`
}
func (ec *Client) BlockNumber(ctx context.Context) (uint64, error) {
var number string
err := ec.c.CallContext(ctx, &number, "eth_blockNumber")
func (ec *Client) BlockNumber(ctx context.Context) (big.Int, error) {
var numberstr string
number := &big.Int{}
err := ec.c.CallContext(ctx, &numberstr, "eth_blockNumber")
if err != nil {
return 0, err
return *number, err
}
return strconv.ParseUint(number, 10, 64)
var ok bool
number, ok = number.SetString(numberstr, 10)
if !ok {
err = errors.New("Failed to parse bigint")
}
return *number, err
}
func (ec *Client) getBlock(ctx context.Context, method string, args ...interface{}) (*types.Block, error) {

View file

@ -365,13 +365,13 @@ func (self *Api) BuildDirectoryTree(mhash string, nameresolver bool) (key storag
}
// Look up mutable resource updates at specific periods and versions
func (self *Api) DbLookup(key storage.Key, name string, period uint32, version uint32) (storage.Key, io.ReadSeeker, int, error) {
func (self *Api) DbLookup(key storage.Key, name string, period uint32, version uint32) (storage.Key, []byte, error) {
var err error
if version != 0 {
if period == 0 {
currentblocknumber, err := self.resource.GetBlock()
if err != nil {
return nil, nil, 0, fmt.Errorf("Could not determine latest block: %v", err)
return nil, nil, fmt.Errorf("Could not determine latest block: %v", err)
}
period = self.resource.BlockToPeriod(name, currentblocknumber)
}
@ -382,13 +382,13 @@ func (self *Api) DbLookup(key storage.Key, name string, period uint32, version u
_, err = self.resource.LookupLatestByName(name, true)
}
if err != nil {
return nil, nil, 0, err
return nil, nil, err
}
key, data, err := self.resource.GetContent(name)
if err != nil {
return nil, nil, 0, err
return nil, nil, err
}
return key, bytes.NewReader(data), len(data), nil
return key, data, nil
}
func (self *Api) DbCreate(name string, frequency uint64) (err error) {

View file

@ -110,8 +110,8 @@ func (self *Config) Init(prvKey *ecdsa.PrivateKey) {
self.PublicKey = pubkeyhex
self.BzzKey = keyhex
if self.SwapEnabled {
self.Swap.Init(self.Contract, prvKey)
//self.SyncParams.Init(self.Path)
//self.HiveParams.Init(self.Path)
}
self.StoreParams.Init(self.Path)
}

View file

@ -49,12 +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.StoreParams.ChunkDbPath == one.Path {
t.Fatal("Failed to correctly initialize StoreParams")
}

View file

@ -295,13 +295,12 @@ func (s *Server) HandlePostDb(w http.ResponseWriter, r *Request) {
if r.ContentLength == 0 {
frequency, err := strconv.ParseUint(r.uri.Path, 10, 64)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
http.ServeContent(w, &r.Request, "", time.Now(), bytes.NewReader([]byte(err.Error())))
s.BadRequest(w, r, fmt.Sprintf("Cannot parse frequency parameter: %v", err))
return
}
err = s.api.DbCreate(r.uri.Addr, frequency)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
s.Error(w, r, fmt.Errorf("Resource creation failed: %v", err))
return
}
} else {
@ -324,8 +323,8 @@ func (s *Server) HandlePostDb(w http.ResponseWriter, r *Request) {
// bzz-db[-[immutable|-raw]]://<id> - get latest update
// bzz-db[-[immutable|-raw]]://<id>/<n> - get latest update on period n
// bzz-db[-[immutable|-raw]]://<id>/<n>/<m> - get update version m of period n
// <id> = ens name or hash
func (s *Server) HandleGetDb(w http.ResponseWriter, r *Request) {
w.Header().Set("Content-Type", "application/octet-stream")
rootKey, err := s.api.Resolve(r.uri)
if err != nil {
@ -340,34 +339,39 @@ func (s *Server) HandleGetDb(w http.ResponseWriter, r *Request) {
var updateKey storage.Key
var period uint64
var version uint64
var data io.ReadSeeker
var data []byte
var dataLength int
now := time.Now()
switch len(params) {
case 0:
updateKey, data, dataLength, err = s.api.DbLookup(rootKey, r.uri.Addr, 0, 0)
break
updateKey, data, err = s.api.DbLookup(rootKey, r.uri.Addr, 0, 0)
case 2:
version, err = strconv.ParseUint(params[1], 10, 32)
if err != nil {
break
}
updateKey, data, err = s.api.DbLookup(rootKey, r.uri.Addr, uint32(period), uint32(version))
case 1:
version, err = strconv.ParseUint(params[1], 10, 32)
if err != nil {
break
}
period, err = strconv.ParseUint(params[0], 10, 32)
if err != nil {
break
}
updateKey, data, dataLength, err = s.api.DbLookup(rootKey, r.uri.Addr, uint32(period), uint32(version))
break
updateKey, data, err = s.api.DbLookup(rootKey, r.uri.Addr, uint32(period), uint32(version))
default:
w.WriteHeader(http.StatusBadRequest)
err = fmt.Errorf("params 0-2")
s.BadRequest(w, r, fmt.Sprintf("Invalid mutable resource request"))
return
}
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
s.Error(w, r, fmt.Errorf("Mutable resource lookup failed: %v", err))
return
}
if !r.uri.DbRaw() {
w.Header().Set("Content-Type", "application/octet-stream")
} else {
entry := api.ManifestEntry{
Hash: rootKey.Hex(),
Path: updateKey.Hex(),
@ -376,9 +380,9 @@ func (s *Server) HandleGetDb(w http.ResponseWriter, r *Request) {
ModTime: now,
Status: http.StatusOK,
}
mode := (6 << 2) | (4 << 1) | 4
mode := 0644
if s.api.DbIsValidated() {
mode |= 2 << 1
mode |= (2 << 3) | 2
}
entry.Mode = int64(mode)
manifest := api.Manifest{
@ -388,12 +392,13 @@ func (s *Server) HandleGetDb(w http.ResponseWriter, r *Request) {
}
manifestJson, err := json.Marshal(manifest)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
s.Error(w, r, fmt.Errorf("Could not convert manifest to json: %v", err))
return
}
data = bytes.NewReader(manifestJson)
w.Header().Set("Content-Type", api.DbManifestType)
data = []byte(manifestJson)
}
http.ServeContent(w, &r.Request, "", now, data)
http.ServeContent(w, &r.Request, "", now, bytes.NewReader(data))
}
// HandleGet handles a GET request to

View file

@ -47,46 +47,53 @@ func TestBzzGetDb(t *testing.T) {
keybytes := make([]byte, common.HashLength) // nearest we get to source of info
_, err := rand.Read(keybytes)
if err != nil {
fmt.Printf("err: %v\n", err)
return
t.Fatal(err)
}
url := fmt.Sprintf("%s/bzz-db:/%s/42", srv.URL, fmt.Sprintf("%x", keybytes))
resp, err := http.Post(url, "application/octet-stream", nil)
if err != nil {
fmt.Printf("err: %v\n", err)
return
t.Fatal(err)
}
b, err := ioutil.ReadAll(resp.Body)
fmt.Printf("Create: %s : %s\n", resp.Status, b)
if err != nil {
t.Fatal(err)
}
log.Debug("Create", "status", resp.Status, "body", b)
url = fmt.Sprintf("%s/bzz-db:/%s", srv.URL, fmt.Sprintf("%x", keybytes))
url = fmt.Sprintf("%s/bzz-db:/%x", srv.URL, keybytes)
data := []byte("foo")
resp, err = http.Post(url, "application/octet-stream", bytes.NewReader(data))
if err != nil {
fmt.Printf("err: %v\n", err)
return
t.Fatal(err)
}
b, err = ioutil.ReadAll(resp.Body)
fmt.Printf("Update: %s : %s\n", resp.Status, b)
if err != nil {
t.Fatal(err)
}
log.Debug("Update", "status", resp.Status, "body", b)
url = fmt.Sprintf("%s/bzz-db-raw:/%s", srv.URL, fmt.Sprintf("%x", keybytes))
resp, err = http.Get(url)
if err != nil {
fmt.Printf("err: %v\n", err)
return
t.Fatal(err)
}
b, err = ioutil.ReadAll(resp.Body)
fmt.Printf("Get: %s : %s\n", resp.Status, b)
if err != nil {
t.Fatal(err)
}
log.Debug("Get raw", "status", resp.Status, "body", b)
url = fmt.Sprintf("%s/bzz-db:/%s", srv.URL, fmt.Sprintf("%x", keybytes))
resp, err = http.Get(url)
if err != nil {
fmt.Printf("err: %v\n", err)
return
t.Fatal(err)
}
b, err = ioutil.ReadAll(resp.Body)
fmt.Printf("Get: %s : %s\n", resp.Status, b)
if err != nil {
t.Fatal(err)
}
log.Debug("Get manifest", "status", resp.Status, "body", b)
}

View file

@ -4,6 +4,7 @@ import (
"context"
"encoding/binary"
"fmt"
"math/big"
"path/filepath"
"sync"
"time"
@ -12,7 +13,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
)
@ -58,6 +58,10 @@ type ResourceValidator interface {
sign(common.Hash) (Signature, error) // SignFunc
}
type ethApi interface {
BlockNumber(context.Context) (big.Int, error)
}
// Mutable resource is an entity which allows updates to a resource
// without resorting to ENS on each update.
// The update scheme is built on swarm chunks with chunk keys following
@ -119,8 +123,10 @@ type ResourceValidator interface {
// TODO: Include modtime in chunk data + signature
type ResourceHandler struct {
ChunkStore
ctx context.Context
cancelFunc func()
validator ResourceValidator
ethClient *ethclient.Client
ethClient ethApi
resources map[string]*resource
hashLock sync.Mutex
resourceLock sync.RWMutex
@ -134,7 +140,7 @@ type ResourceHandler struct {
// Create or open resource update chunk store
//
// If validator is nil, signature and access validation will be deactivated
func NewResourceHandler(datadir string, cloudStore CloudStore, ethClient *ethclient.Client, validator ResourceValidator) (*ResourceHandler, error) {
func NewResourceHandler(datadir string, cloudStore CloudStore, ethClient ethApi, validator ResourceValidator) (*ResourceHandler, error) {
hashfunc := MakeHashFunc(SHA3Hash)
@ -602,17 +608,11 @@ func (self *ResourceHandler) Close() {
}
func (self *ResourceHandler) GetBlock() (uint64, error) {
return self.ethClient.BlockNumber(self.ctx)
// get the block height and convert to uint64
// var currentblock string
// err := self.rpcClient.Call(&currentblock, "eth_blockNumber")
// if err != nil {
// return 0, err
// }
// if currentblock == "0x0" {
// return 0, nil
// }
// return strconv.ParseUint(currentblock, 10, 64)
bigblocknumber, err := self.ethClient.BlockNumber(self.ctx)
if err != nil {
return 0, err
}
return bigblocknumber.Uint64(), nil
}
// Calculate the period index (aka major version number) from a given block number
@ -776,10 +776,7 @@ func isSafeName(name string) bool {
if err != nil {
return false
}
if validname != name {
return false
}
return true
return validname == name
}
// convenience for creating signature hashes of update data

View file

@ -2,6 +2,7 @@ package storage
import (
"bytes"
"context"
"crypto/ecdsa"
"crypto/rand"
"encoding/binary"
@ -9,8 +10,6 @@ import (
"io/ioutil"
"math/big"
"os"
"path/filepath"
"strconv"
"strings"
"testing"
"time"
@ -22,9 +21,7 @@ import (
"github.com/ethereum/go-ethereum/contracts/ens/contract"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
)
var (
@ -50,7 +47,7 @@ func init() {
// so we use this wrapper to fake returning the block count
type fakeBackend struct {
*backends.SimulatedBackend
blocknumber uint64
blocknumber int64
}
func (f *fakeBackend) Commit() {
@ -60,13 +57,10 @@ func (f *fakeBackend) Commit() {
f.blocknumber++
}
// for faking the rpc service, since we don't need the whole node stack
type FakeRPC struct {
backend *fakeBackend
}
func (r *FakeRPC) BlockNumber() (string, error) {
return strconv.FormatUint(r.backend.blocknumber, 10), nil
func (f *fakeBackend) BlockNumber(context context.Context) (big.Int, error) {
f.blocknumber++
biggie := big.NewInt(f.blocknumber)
return *biggie, nil
}
// check that signature address matches update signer address
@ -84,8 +78,9 @@ func TestResourceReverse(t *testing.T) {
// set up rpc and create resourcehandler
rh, _, _, teardownTest, err := setupTest(nil, newTestValidator(signer.signContent))
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
defer teardownTest()
// generate a hash for block 4200 version 1
key := rh.resourceHash(period, version, rh.nameHash(safeName))
@ -94,14 +89,14 @@ func TestResourceReverse(t *testing.T) {
data := make([]byte, 8)
_, err = rand.Read(data)
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
testHasher.Reset()
testHasher.Write(data)
digest := rh.keyDataHash(key, data)
sig, err := rh.validator.sign(digest)
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
chunk := newUpdateChunk(key, &sig, period, version, safeName, data)
@ -111,31 +106,30 @@ func TestResourceReverse(t *testing.T) {
checkdigest := rh.keyDataHash(chunk.Key, checkdata)
recoveredaddress, err := getAddressFromDataSig(checkdigest, *checksig)
if err != nil {
teardownTest(t, fmt.Errorf("Retrieve address from signature fail: %v", err))
t.Fatalf("Retrieve address from signature fail: %v", err)
}
originaladdress := crypto.PubkeyToAddress(signer.privKey.PublicKey)
// check that the metadata retrieved from the chunk matches what we gave it
if recoveredaddress != originaladdress {
teardownTest(t, fmt.Errorf("addresses dont match: %x != %x", originaladdress, recoveredaddress))
t.Fatalf("addresses dont match: %x != %x", originaladdress, recoveredaddress)
}
if !bytes.Equal(key[:], chunk.Key[:]) {
teardownTest(t, fmt.Errorf("Expected chunk key '%x', was '%x'", key, chunk.Key))
t.Fatalf("Expected chunk key '%x', was '%x'", key, chunk.Key)
}
if period != checkperiod {
teardownTest(t, fmt.Errorf("Expected period '%d', was '%d'", period, checkperiod))
t.Fatalf("Expected period '%d', was '%d'", period, checkperiod)
}
if version != checkversion {
teardownTest(t, fmt.Errorf("Expected version '%d', was '%d'", version, checkversion))
t.Fatalf("Expected version '%d', was '%d'", version, checkversion)
}
if safeName != checkname {
teardownTest(t, fmt.Errorf("Expected name '%s', was '%s'", safeName, checkname))
t.Fatalf("Expected name '%s', was '%s'", safeName, checkname)
}
if !bytes.Equal(data, checkdata) {
teardownTest(t, fmt.Errorf("Expectedn data '%x', was '%x'", data, checkdata))
t.Fatalf("Expectedn data '%x', was '%x'", data, checkdata)
}
teardownTest(t, nil)
}
// make updates and retrieve them based on periods and versions
@ -143,34 +137,35 @@ func TestResourceHandler(t *testing.T) {
// make fake backend, set up rpc and create resourcehandler
backend := &fakeBackend{
blocknumber: startBlock,
blocknumber: int64(startBlock),
}
rh, datadir, _, teardownTest, err := setupTest(backend, nil)
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
defer teardownTest()
// create a new resource
_, err = rh.NewResource(safeName, resourceFrequency)
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
// check that the new resource is stored correctly
namehash := rh.nameHash(safeName)
chunk, err := rh.ChunkStore.(*resourceChunkStore).localStore.(*LocalStore).memStore.Get(Key(namehash[:]))
if err != nil {
teardownTest(t, err)
t.Fatal(err)
} else if len(chunk.SData) < 16 {
teardownTest(t, fmt.Errorf("chunk data must be minimum 16 bytes, is %d", len(chunk.SData)))
t.Fatalf("chunk data must be minimum 16 bytes, is %d", len(chunk.SData))
}
startblocknumber := binary.LittleEndian.Uint64(chunk.SData[:8])
chunkfrequency := binary.LittleEndian.Uint64(chunk.SData[8:])
if startblocknumber != backend.blocknumber {
teardownTest(t, fmt.Errorf("stored block number %d does not match provided block number %d", startblocknumber, backend.blocknumber))
if startblocknumber != uint64(backend.blocknumber) {
t.Fatalf("stored block number %d does not match provided block number %d", startblocknumber, backend.blocknumber)
}
if chunkfrequency != resourceFrequency {
teardownTest(t, fmt.Errorf("stored frequency %d does not match provided frequency %d", chunkfrequency, resourceFrequency))
t.Fatalf("stored frequency %d does not match provided frequency %d", chunkfrequency, resourceFrequency)
}
// update halfway to first period
@ -179,7 +174,7 @@ func TestResourceHandler(t *testing.T) {
data := []byte("blinky")
resourcekey["blinky"], err = rh.Update(safeName, data)
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
// update on first period
@ -187,7 +182,7 @@ func TestResourceHandler(t *testing.T) {
data = []byte("pinky")
resourcekey["pinky"], err = rh.Update(safeName, data)
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
// update on second period
@ -195,7 +190,7 @@ func TestResourceHandler(t *testing.T) {
data = []byte("inky")
resourcekey["inky"], err = rh.Update(safeName, data)
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
// update just after second period
@ -203,7 +198,7 @@ func TestResourceHandler(t *testing.T) {
data = []byte("clyde")
resourcekey["clyde"], err = rh.Update(safeName, data)
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
time.Sleep(time.Second)
rh.Close()
@ -215,43 +210,42 @@ func TestResourceHandler(t *testing.T) {
rh2, err := NewResourceHandler(datadir, &testCloudStore{}, rh.ethClient, nil)
_, err = rh2.LookupLatestByName(safeName, true)
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
// last update should be "clyde", version two, blockheight startblocknumber + (resourcefrequency * 3)
if !bytes.Equal(rh2.resources[safeName].data, []byte("clyde")) {
teardownTest(t, fmt.Errorf("resource data was %v, expected %v", rh2.resources[safeName].data, []byte("clyde")))
t.Fatalf("resource data was %v, expected %v", rh2.resources[safeName].data, []byte("clyde"))
}
if rh2.resources[safeName].version != 2 {
teardownTest(t, fmt.Errorf("resource version was %d, expected 2", rh2.resources[safeName].version))
t.Fatalf("resource version was %d, expected 2", rh2.resources[safeName].version)
}
if rh2.resources[safeName].lastPeriod != 3 {
teardownTest(t, fmt.Errorf("resource period was %d, expected 3", rh2.resources[safeName].lastPeriod))
t.Fatalf("resource period was %d, expected 3", rh2.resources[safeName].lastPeriod)
}
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)
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
// check data
if !bytes.Equal(rsrc.data, []byte("clyde")) {
teardownTest(t, fmt.Errorf("resource data (historical) was %v, expected %v", rh2.resources[domainName].data, []byte("clyde")))
t.Fatalf("resource data (historical) was %v, expected %v", rh2.resources[domainName].data, []byte("clyde"))
}
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)
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
// check data
if !bytes.Equal(rsrc.data, []byte("inky")) {
teardownTest(t, fmt.Errorf("resource data (historical) was %v, expected %v", rh2.resources[domainName].data, []byte("inky")))
t.Fatalf("resource data (historical) was %v, expected %v", rh2.resources[domainName].data, []byte("inky"))
}
log.Debug("Specific version lookup", "period", rh2.resources[safeName].lastPeriod, "version", rh2.resources[safeName].version, "data", rh2.resources[safeName].data)
teardownTest(t, nil)
}
@ -283,34 +277,33 @@ func TestResourceENSOwner(t *testing.T) {
// set up rpc and create resourcehandler with ENS sim backend
rh, _, _, teardownTest, err := setupTest(contractbackend, validator)
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
defer teardownTest()
// create new resource when we are owner = ok
_, err = rh.NewResource(safeName, resourceFrequency)
if err != nil {
teardownTest(t, fmt.Errorf("Create resource fail: %v", err))
t.Fatalf("Create resource fail: %v", err)
}
data := []byte("foo")
// update resource when we are owner = ok
_, err = rh.Update(safeName, data)
if err != nil {
teardownTest(t, fmt.Errorf("Update resource fail: %v", err))
t.Fatalf("Update resource fail: %v", err)
}
// update resource when we are owner = ok
signertwo, err := newTestSigner()
if err != nil {
teardownTest(t, err)
t.Fatal(err)
}
rh.validator.(*ENSValidator).signFunc = signertwo.signContent
_, err = rh.Update(safeName, data)
if err == nil {
teardownTest(t, fmt.Errorf("Expected resource update fail due to owner mismatch"))
t.Fatalf("Expected resource update fail due to owner mismatch")
}
teardownTest(t, nil)
}
// fast-forward blockheight
@ -321,7 +314,7 @@ func fwdBlocks(count int, backend *fakeBackend) {
}
// create rpc and resourcehandler
func setupTest(contractbackend bind.ContractBackend, validator ResourceValidator) (rh *ResourceHandler, datadir string, signer *testSigner, teardown func(*testing.T, error), err error) {
func setupTest(backend ethApi, validator ResourceValidator) (rh *ResourceHandler, datadir string, signer *testSigner, teardown func(), err error) {
var fsClean func()
var rpcClean func()
@ -337,55 +330,18 @@ func setupTest(contractbackend bind.ContractBackend, validator ResourceValidator
// temp datadir
datadir, err = ioutil.TempDir("", "rh")
if err != nil {
return
return nil, "", nil, nil, err
}
fsClean = func() {
os.RemoveAll(datadir)
}
// starting the whole stack just to get blocknumbers is too cumbersome
// so we fake the rpc server to get blocknumbers for testing
ipcpath := filepath.Join(datadir, "test.ipc")
ipcl, err := rpc.CreateIPCListener(ipcpath)
if err != nil {
return
}
rpcserver := rpc.NewServer()
var fake *fakeBackend
if contractbackend != nil {
fake = contractbackend.(*fakeBackend)
}
rpcserver.RegisterName("eth", &FakeRPC{
backend: fake,
})
go func() {
rpcserver.ServeListener(ipcl)
}()
rpcClean = func() {
rpcserver.Stop()
}
// connect to fake rpc
rpcClient, err := rpc.Dial(ipcpath)
if err != nil {
return
}
ethClient := ethclient.NewClient(rpcClient)
rh, err = NewResourceHandler(datadir, &testCloudStore{}, ethClient, validator)
teardown = func(t *testing.T, err error) {
cleanF()
if err != nil {
t.Fatal(err)
}
}
return
rh, err = NewResourceHandler(datadir, &testCloudStore{}, backend, validator)
return rh, datadir, signer, cleanF, nil
}
// Set up simulated ENS backend for use with ENSResourceHandler tests
func setupENS(addr common.Address, transactOpts *bind.TransactOpts, sub string, top string) (common.Address, bind.ContractBackend, error) {
func setupENS(addr common.Address, transactOpts *bind.TransactOpts, sub string, top string) (common.Address, *fakeBackend, error) {
// create the domain hash values to pass to the ENS contract methods
var tophash [32]byte

View file

@ -58,8 +58,6 @@ type Swarm struct {
bzz *network.Bzz // the logistic manager
backend chequebook.Backend // simple blockchain Backend
privateKey *ecdsa.PrivateKey
corsString string
swapEnabled bool
lstore *storage.LocalStore // local store, needs to store for releasing resources after node stopped
sfs *fuse.SwarmFS // need this to cleanup all the active mounts on node exit
ps *pss.Pss
@ -83,7 +81,7 @@ func (self *Swarm) API() *SwarmAPI {
// implements node.Service
// If mockStore is not nil, it will be used as the storage for chunk data.
// MockStore should be used only for testing.
func NewSwarm(ctx *node.ServiceContext, backend chequebook.Backend, ensClient *ethclient.Client, config *api.Config, swapEnabled, syncEnabled bool, cors string, pssEnabled bool, resourceEnabled bool, mockStore *mock.NodeStore) (self *Swarm, err error) {
func NewSwarm(ctx *node.ServiceContext, backend chequebook.Backend, ensClient *ethclient.Client, config *api.Config, mockStore *mock.NodeStore) (self *Swarm, err error) {
if bytes.Equal(common.FromHex(config.PublicKey), storage.ZeroKey) {
return nil, fmt.Errorf("empty public key")
@ -94,10 +92,8 @@ func NewSwarm(ctx *node.ServiceContext, backend chequebook.Backend, ensClient *e
self = &Swarm{
config: config,
swapEnabled: swapEnabled,
backend: backend,
privateKey: config.Swap.PrivateKey(),
corsString: cors,
}
log.Debug(fmt.Sprintf("Setting up Swarm service components"))
@ -139,7 +135,7 @@ func NewSwarm(ctx *node.ServiceContext, backend chequebook.Backend, ensClient *e
log.Debug(fmt.Sprintf("-> Content Store API"))
// Pss = postal service over swarm (devp2p over bzz)
if pssEnabled {
if self.config.PssEnabled {
pssparams := pss.NewPssParams(self.privateKey)
self.ps = pss.NewPss(to, self.dpa, pssparams)
if pss.IsActiveHandshake {
@ -162,7 +158,7 @@ func NewSwarm(ctx *node.ServiceContext, backend chequebook.Backend, ensClient *e
var resourceHandler *storage.ResourceHandler
// if use resource updates
if resourceEnabled {
if self.config.ResourceEnabled {
var resourceValidator storage.ResourceValidator
if self.dns != nil {
resourceValidator, err = storage.NewENSValidator(config.EnsRoot, ensClient, transactOpts, storage.NewGenericResourceSigner(self.privateKey))
@ -204,7 +200,7 @@ func (self *Swarm) Start(srv *p2p.Server) error {
log.Warn("Updated bzz local addr", "oaddr", fmt.Sprintf("%x", newaddr.OAddr), "uaddr", fmt.Sprintf("%x", newaddr.UAddr))
// set chequebook
if self.swapEnabled {
if self.config.SwapEnabled {
ctx := context.Background() // The initial setup has no deadline.
err := self.SetChequebook(ctx)
if err != nil {
@ -237,14 +233,14 @@ func (self *Swarm) Start(srv *p2p.Server) error {
addr := net.JoinHostPort(self.config.ListenAddr, self.config.Port)
go httpapi.StartHttpServer(self.api, &httpapi.ServerConfig{
Addr: addr,
CorsString: self.corsString,
CorsString: self.config.Cors,
})
}
log.Debug(fmt.Sprintf("Swarm http proxy started on port: %v", self.config.Port))
if self.corsString != "" {
log.Debug(fmt.Sprintf("Swarm http proxy started with corsdomain: %v", self.corsString))
if self.config.Cors != "" {
log.Debug(fmt.Sprintf("Swarm http proxy started with corsdomain: %v", self.config.Cors))
}
return nil

View file

@ -17,21 +17,29 @@
package testutil
import (
"crypto/ecdsa"
"context"
"io/ioutil"
"math/big"
"net/http/httptest"
"os"
"path/filepath"
"strconv"
"testing"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/swarm/api"
httpapi "github.com/ethereum/go-ethereum/swarm/api/http"
"github.com/ethereum/go-ethereum/swarm/storage"
)
type fakeBackend struct {
blocknumber int64
}
func (f *fakeBackend) BlockNumber(ctx context.Context) (big.Int, error) {
f.blocknumber++
biggie := big.NewInt(f.blocknumber)
return *biggie, nil
}
func NewTestSwarmServer(t *testing.T) *TestSwarmServer {
dir, err := ioutil.TempDir("", "swarm-storage-test")
if err != nil {
@ -60,28 +68,8 @@ func NewTestSwarmServer(t *testing.T) *TestSwarmServer {
if err != nil {
t.Fatal(err)
}
ipcPath := filepath.Join(resourceDir, "test.ipc")
ipcl, err := rpc.CreateIPCListener(ipcPath)
if err != nil {
t.Fatal(err)
}
rpcServer := rpc.NewServer()
rpcServer.RegisterName("eth", &FakeRPC{})
go func() {
rpcServer.ServeListener(ipcl)
}()
rpcClean := func() {
rpcServer.Stop()
}
// connect to fake rpc
rpcClient, err := rpc.Dial(ipcPath)
if err != nil {
t.Fatal(err)
}
ethClient := ethclient.NewClient(rpcClient)
rh, err := storage.NewResourceHandler(resourceDir, &testCloudStore{}, ethClient, nil)
rh, err := storage.NewResourceHandler(resourceDir, &testCloudStore{}, &fakeBackend{}, nil)
if err != nil {
t.Fatal(err)
}
@ -94,8 +82,9 @@ func NewTestSwarmServer(t *testing.T) *TestSwarmServer {
dir: dir,
hasher: storage.MakeHashFunc(storage.SHA3Hash)(),
cleanup: func() {
srv.Close()
rh.Close()
rpcClean()
dpa.Stop()
os.RemoveAll(dir)
os.RemoveAll(resourceDir)
},
@ -105,16 +94,13 @@ func NewTestSwarmServer(t *testing.T) *TestSwarmServer {
type TestSwarmServer struct {
*httptest.Server
hasher storage.SwarmHash
privatekey *ecdsa.PrivateKey
Dpa *storage.DPA
dir string
cleanup func()
}
func (t *TestSwarmServer) Close() {
t.Server.Close()
t.Dpa.Stop()
os.RemoveAll(t.dir)
t.cleanup()
}
type testCloudStore struct {