Merge pull request #172 from ethersphere/pss-binary-fix

cmd/swarm: Buildable cli with pss
This commit is contained in:
lash 2017-12-15 15:01:19 +01:00 committed by GitHub
commit 07e47e0abd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 206 additions and 99 deletions

View file

@ -69,6 +69,7 @@ const (
SWARM_ENV_ENS_ADDR = "SWARM_ENS_ADDR" SWARM_ENV_ENS_ADDR = "SWARM_ENS_ADDR"
SWARM_ENV_CORS = "SWARM_CORS" SWARM_ENV_CORS = "SWARM_CORS"
SWARM_ENV_BOOTNODES = "SWARM_BOOTNODES" SWARM_ENV_BOOTNODES = "SWARM_BOOTNODES"
SWARM_ENV_PSS_ENABLE = "SWARM_PSS_ENABLE"
GETH_ENV_DATADIR = "GETH_DATADIR" GETH_ENV_DATADIR = "GETH_DATADIR"
) )
@ -94,7 +95,7 @@ func buildConfig(ctx *cli.Context) (config *bzzapi.Config, err error) {
//check for deprecated flags //check for deprecated flags
checkDeprecated(ctx) checkDeprecated(ctx)
//start by creating a default config //start by creating a default config
config = bzzapi.NewDefaultConfig() config = bzzapi.NewConfig()
//first load settings from config file (if provided) //first load settings from config file (if provided)
config, err = configFileOverride(config, ctx) config, err = configFileOverride(config, ctx)
//override settings provided by environment variables //override settings provided by environment variables
@ -211,6 +212,10 @@ func cmdLineOverride(currentConfig *bzzapi.Config, ctx *cli.Context) *bzzapi.Con
currentConfig.BootNodes = ctx.GlobalString(utils.BootnodesFlag.Name) currentConfig.BootNodes = ctx.GlobalString(utils.BootnodesFlag.Name)
} }
if ctx.GlobalIsSet(SwarmPssEnabledFlag.Name) {
currentConfig.PssEnabled = true
}
return currentConfig return currentConfig
} }
@ -283,6 +288,12 @@ func envVarsOverride(currentConfig *bzzapi.Config) (config *bzzapi.Config) {
currentConfig.BootNodes = bootnodes currentConfig.BootNodes = bootnodes
} }
if pssenable := os.Getenv(SWARM_ENV_PSS_ENABLE); pssenable != "" {
if ps, err := strconv.ParseBool(pssenable); err != nil {
currentConfig.PssEnabled = ps
}
}
return currentConfig return currentConfig
} }

View file

@ -34,7 +34,7 @@ import (
func TestDumpConfig(t *testing.T) { func TestDumpConfig(t *testing.T) {
swarm := runSwarm(t, "dumpconfig") swarm := runSwarm(t, "dumpconfig")
defaultConf := api.NewDefaultConfig() defaultConf := api.NewConfig()
out, err := tomlSettings.Marshal(&defaultConf) out, err := tomlSettings.Marshal(&defaultConf)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -43,7 +43,7 @@ func TestDumpConfig(t *testing.T) {
swarm.ExpectExit() swarm.ExpectExit()
} }
func TestFailsSwapEnabledNoSwapApi(t *testing.T) { func TestConfigFailsSwapEnabledNoSwapApi(t *testing.T) {
flags := []string{ flags := []string{
fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42", fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42",
fmt.Sprintf("--%s", SwarmPortFlag.Name), "54545", fmt.Sprintf("--%s", SwarmPortFlag.Name), "54545",
@ -55,7 +55,7 @@ func TestFailsSwapEnabledNoSwapApi(t *testing.T) {
swarm.ExpectExit() swarm.ExpectExit()
} }
func TestFailsNoBzzAccount(t *testing.T) { func TestConfigFailsNoBzzAccount(t *testing.T) {
flags := []string{ flags := []string{
fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42", fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42",
fmt.Sprintf("--%s", SwarmPortFlag.Name), "54545", fmt.Sprintf("--%s", SwarmPortFlag.Name), "54545",
@ -66,7 +66,7 @@ func TestFailsNoBzzAccount(t *testing.T) {
swarm.ExpectExit() swarm.ExpectExit()
} }
func TestCmdLineOverrides(t *testing.T) { func TestConfigCmdLineOverrides(t *testing.T) {
dir, err := ioutil.TempDir("", "bzztest") dir, err := ioutil.TempDir("", "bzztest")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -86,6 +86,7 @@ func TestCmdLineOverrides(t *testing.T) {
fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42", fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "42",
fmt.Sprintf("--%s", SwarmPortFlag.Name), httpPort, fmt.Sprintf("--%s", SwarmPortFlag.Name), httpPort,
fmt.Sprintf("--%s", SwarmSyncEnabledFlag.Name), fmt.Sprintf("--%s", SwarmSyncEnabledFlag.Name),
fmt.Sprintf("--%s", SwarmPssEnabledFlag.Name),
fmt.Sprintf("--%s", CorsStringFlag.Name), "*", fmt.Sprintf("--%s", CorsStringFlag.Name), "*",
fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(), fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(),
fmt.Sprintf("--%s", EnsAPIFlag.Name), "", fmt.Sprintf("--%s", EnsAPIFlag.Name), "",
@ -128,6 +129,10 @@ func TestCmdLineOverrides(t *testing.T) {
t.Fatal("Expected Sync to be enabled, but is false") t.Fatal("Expected Sync to be enabled, but is false")
} }
if !info.PssEnabled {
t.Fatal("Expected Pss to be enabled, but is false")
}
if info.Cors != "*" { if info.Cors != "*" {
t.Fatalf("Expected Cors flag to be set to %s, got %s", "*", info.Cors) t.Fatalf("Expected Cors flag to be set to %s, got %s", "*", info.Cors)
} }
@ -135,7 +140,7 @@ func TestCmdLineOverrides(t *testing.T) {
node.Shutdown() node.Shutdown()
} }
func TestFileOverrides(t *testing.T) { func TestConfigFileOverrides(t *testing.T) {
// assign ports // assign ports
httpPort, err := assignTCPPort() httpPort, err := assignTCPPort()
@ -145,16 +150,17 @@ func TestFileOverrides(t *testing.T) {
//create a config file //create a config file
//first, create a default conf //first, create a default conf
defaultConf := api.NewDefaultConfig() defaultConf := api.NewConfig()
//change some values in order to test if they have been loaded //change some values in order to test if they have been loaded
defaultConf.SyncEnabled = true defaultConf.SyncEnabled = true
defaultConf.PssEnabled = true
defaultConf.NetworkId = 54 defaultConf.NetworkId = 54
defaultConf.Port = httpPort defaultConf.Port = httpPort
defaultConf.StoreParams.DbCapacity = 9000000 defaultConf.StoreParams.DbCapacity = 9000000
defaultConf.ChunkerParams.Branches = 64 defaultConf.ChunkerParams.Branches = 64
defaultConf.HiveParams.CallInterval = 6000000000 defaultConf.HiveParams.KeepAliveInterval = 6000000000
defaultConf.Swap.Params.Strategy.AutoCashInterval = 600 * time.Second defaultConf.Swap.Params.Strategy.AutoCashInterval = 600 * time.Second
defaultConf.SyncParams.KeyBufferSize = 512 //defaultConf.SyncParams.KeyBufferSize = 512
//create a TOML string //create a TOML string
out, err := tomlSettings.Marshal(&defaultConf) out, err := tomlSettings.Marshal(&defaultConf)
if err != nil { if err != nil {
@ -223,6 +229,10 @@ func TestFileOverrides(t *testing.T) {
t.Fatal("Expected Sync to be enabled, but is false") t.Fatal("Expected Sync to be enabled, but is false")
} }
if !info.PssEnabled {
t.Fatal("Expected Pss to be enabled, but is false")
}
if info.StoreParams.DbCapacity != 9000000 { if info.StoreParams.DbCapacity != 9000000 {
t.Fatalf("Expected network ID to be %d, got %d", 54, info.NetworkId) t.Fatalf("Expected network ID to be %d, got %d", 54, info.NetworkId)
} }
@ -231,22 +241,22 @@ func TestFileOverrides(t *testing.T) {
t.Fatalf("Expected chunker params branches to be %d, got %d", 64, info.ChunkerParams.Branches) t.Fatalf("Expected chunker params branches to be %d, got %d", 64, info.ChunkerParams.Branches)
} }
if info.HiveParams.CallInterval != 6000000000 { if info.HiveParams.KeepAliveInterval != 6000000000 {
t.Fatalf("Expected HiveParams CallInterval to be %d, got %d", uint64(6000000000), uint64(info.HiveParams.CallInterval)) t.Fatalf("Expected HiveParams KeepAliveInterval to be %d, got %d", uint64(6000000000), uint64(info.HiveParams.KeepAliveInterval))
} }
if info.Swap.Params.Strategy.AutoCashInterval != 600*time.Second { if info.Swap.Params.Strategy.AutoCashInterval != 600*time.Second {
t.Fatalf("Expected SwapParams AutoCashInterval to be %ds, got %d", 600, info.Swap.Params.Strategy.AutoCashInterval) t.Fatalf("Expected SwapParams AutoCashInterval to be %ds, got %d", 600, info.Swap.Params.Strategy.AutoCashInterval)
} }
if info.SyncParams.KeyBufferSize != 512 { // if info.SyncParams.KeyBufferSize != 512 {
t.Fatalf("Expected info.SyncParams.KeyBufferSize to be %d, got %d", 512, info.SyncParams.KeyBufferSize) // t.Fatalf("Expected info.SyncParams.KeyBufferSize to be %d, got %d", 512, info.SyncParams.KeyBufferSize)
} // }
node.Shutdown() node.Shutdown()
} }
func TestEnvVars(t *testing.T) { func TestConfigEnvVars(t *testing.T) {
// assign ports // assign ports
httpPort, err := assignTCPPort() httpPort, err := assignTCPPort()
if err != nil { if err != nil {
@ -258,6 +268,7 @@ func TestEnvVars(t *testing.T) {
envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmNetworkIdFlag.EnvVar, "999")) envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmNetworkIdFlag.EnvVar, "999"))
envVars = append(envVars, fmt.Sprintf("%s=%s", CorsStringFlag.EnvVar, "*")) envVars = append(envVars, fmt.Sprintf("%s=%s", CorsStringFlag.EnvVar, "*"))
envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmSyncEnabledFlag.EnvVar, "true")) envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmSyncEnabledFlag.EnvVar, "true"))
envVars = append(envVars, fmt.Sprintf("%s=%s", SwarmPssEnabledFlag.EnvVar, "true"))
dir, err := ioutil.TempDir("", "bzztest") dir, err := ioutil.TempDir("", "bzztest")
if err != nil { if err != nil {
@ -338,11 +349,15 @@ func TestEnvVars(t *testing.T) {
t.Fatal("Expected Sync to be enabled, but is false") t.Fatal("Expected Sync to be enabled, but is false")
} }
if !info.PssEnabled {
t.Fatal("Expected Pss to be enabled, but is false")
}
node.Shutdown() node.Shutdown()
cmd.Process.Kill() cmd.Process.Kill()
} }
func TestCmdLineOverridesFile(t *testing.T) { func TestConfigCmdLineOverridesFile(t *testing.T) {
// assign ports // assign ports
httpPort, err := assignTCPPort() httpPort, err := assignTCPPort()
@ -352,16 +367,17 @@ func TestCmdLineOverridesFile(t *testing.T) {
//create a config file //create a config file
//first, create a default conf //first, create a default conf
defaultConf := api.NewDefaultConfig() defaultConf := api.NewConfig()
//change some values in order to test if they have been loaded //change some values in order to test if they have been loaded
defaultConf.SyncEnabled = false defaultConf.SyncEnabled = false
defaultConf.PssEnabled = false
defaultConf.NetworkId = 54 defaultConf.NetworkId = 54
defaultConf.Port = "8588" defaultConf.Port = "8588"
defaultConf.StoreParams.DbCapacity = 9000000 defaultConf.StoreParams.DbCapacity = 9000000
defaultConf.ChunkerParams.Branches = 64 defaultConf.ChunkerParams.Branches = 64
defaultConf.HiveParams.CallInterval = 6000000000 defaultConf.HiveParams.KeepAliveInterval = 6000000000
defaultConf.Swap.Params.Strategy.AutoCashInterval = 600 * time.Second defaultConf.Swap.Params.Strategy.AutoCashInterval = 600 * time.Second
defaultConf.SyncParams.KeyBufferSize = 512 //defaultConf.SyncParams.KeyBufferSize = 512
//create a TOML file //create a TOML file
out, err := tomlSettings.Marshal(&defaultConf) out, err := tomlSettings.Marshal(&defaultConf)
if err != nil { if err != nil {
@ -393,6 +409,7 @@ func TestCmdLineOverridesFile(t *testing.T) {
fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "77", fmt.Sprintf("--%s", SwarmNetworkIdFlag.Name), "77",
fmt.Sprintf("--%s", SwarmPortFlag.Name), httpPort, fmt.Sprintf("--%s", SwarmPortFlag.Name), httpPort,
fmt.Sprintf("--%s", SwarmSyncEnabledFlag.Name), fmt.Sprintf("--%s", SwarmSyncEnabledFlag.Name),
fmt.Sprintf("--%s", SwarmPssEnabledFlag.Name),
fmt.Sprintf("--%s", SwarmTomlConfigPathFlag.Name), f.Name(), fmt.Sprintf("--%s", SwarmTomlConfigPathFlag.Name), f.Name(),
fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(), fmt.Sprintf("--%s", SwarmAccountFlag.Name), account.Address.String(),
"--ens-api", "", "--ens-api", "",
@ -443,17 +460,21 @@ func TestCmdLineOverridesFile(t *testing.T) {
t.Fatalf("Expected chunker params branches to be %d, got %d", 64, info.ChunkerParams.Branches) t.Fatalf("Expected chunker params branches to be %d, got %d", 64, info.ChunkerParams.Branches)
} }
if info.HiveParams.CallInterval != 6000000000 { if info.HiveParams.KeepAliveInterval != 6000000000 {
t.Fatalf("Expected HiveParams CallInterval to be %d, got %d", uint64(6000000000), uint64(info.HiveParams.CallInterval)) t.Fatalf("Expected HiveParams KeepAliveInterval to be %d, got %d", uint64(6000000000), uint64(info.HiveParams.KeepAliveInterval))
} }
if info.Swap.Params.Strategy.AutoCashInterval != 600*time.Second { if info.Swap.Params.Strategy.AutoCashInterval != 600*time.Second {
t.Fatalf("Expected SwapParams AutoCashInterval to be %ds, got %d", 600, info.Swap.Params.Strategy.AutoCashInterval) t.Fatalf("Expected SwapParams AutoCashInterval to be %ds, got %d", 600, info.Swap.Params.Strategy.AutoCashInterval)
} }
if info.SyncParams.KeyBufferSize != 512 { if !info.PssEnabled {
t.Fatalf("Expected info.SyncParams.KeyBufferSize to be %d, got %d", 512, info.SyncParams.KeyBufferSize) t.Fatal("Expected Pss to be enabled, but is false")
} }
// if info.SyncParams.KeyBufferSize != 512 {
// t.Fatalf("Expected info.SyncParams.KeyBufferSize to be %d, got %d", 512, info.SyncParams.KeyBufferSize)
// }
node.Shutdown() node.Shutdown()
} }

View file

@ -145,6 +145,10 @@ var (
Name: "mime", Name: "mime",
Usage: "force mime type", Usage: "force mime type",
} }
SwarmPssEnabledFlag = cli.BoolFlag{
Name: "pss",
Usage: "Enable pss (message passing over swarm)",
}
CorsStringFlag = cli.StringFlag{ CorsStringFlag = cli.StringFlag{
Name: "corsdomain", Name: "corsdomain",
Usage: "Domain on which to send Access-Control-Allow-Origin header (multiple domains can be supplied separated by a ',')", Usage: "Domain on which to send Access-Control-Allow-Origin header (multiple domains can be supplied separated by a ',')",
@ -361,9 +365,19 @@ DEPRECATED: use 'swarm db clean'.
SwarmUploadDefaultPath, SwarmUploadDefaultPath,
SwarmUpFromStdinFlag, SwarmUpFromStdinFlag,
SwarmUploadMimeType, SwarmUploadMimeType,
// pss flags
SwarmPssEnabledFlag,
//deprecated flags //deprecated flags
DeprecatedEthAPIFlag, DeprecatedEthAPIFlag,
} }
rpcFlags := []cli.Flag{
utils.WSEnabledFlag,
utils.WSListenAddrFlag,
utils.WSPortFlag,
utils.WSApiFlag,
utils.WSAllowedOriginsFlag,
}
app.Flags = append(app.Flags, rpcFlags...)
app.Flags = append(app.Flags, debug.Flags...) app.Flags = append(app.Flags, debug.Flags...)
app.Before = func(ctx *cli.Context) error { app.Before = func(ctx *cli.Context) error {
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())
@ -514,7 +528,7 @@ func registerBzzService(bzzconfig *bzzapi.Config, ctx *cli.Context, stack *node.
} }
} }
return swarm.NewSwarm(ctx, swapClient, ensClient, bzzconfig, bzzconfig.SwapEnabled, bzzconfig.SyncEnabled, bzzconfig.Cors) return swarm.NewSwarm(ctx, swapClient, ensClient, bzzconfig, bzzconfig.SwapEnabled, bzzconfig.SyncEnabled, bzzconfig.Cors, bzzconfig.PssEnabled)
} }
//register within the ethereum node //register within the ethereum node
if err := stack.Register(boot); err != nil { if err := stack.Register(boot); err != nil {

View file

@ -27,6 +27,8 @@ import (
// TestCLISwarmUp tests that running 'swarm up' makes the resulting file // TestCLISwarmUp tests that running 'swarm up' makes the resulting file
// available from all nodes via the HTTP API // available from all nodes via the HTTP API
func TestCLISwarmUp(t *testing.T) { func TestCLISwarmUp(t *testing.T) {
// skipped because syncer is not functional
t.Skip()
// start 3 node cluster // start 3 node cluster
t.Log("starting 3 node cluster") t.Log("starting 3 node cluster")
cluster := newTestCluster(t, 3) cluster := newTestCluster(t, 3)

View file

@ -45,7 +45,7 @@ type Config struct {
*storage.ChunkerParams *storage.ChunkerParams
*network.HiveParams *network.HiveParams
Swap *swap.SwapParams Swap *swap.SwapParams
*network.SyncParams //*network.SyncParams
Contract common.Address Contract common.Address
EnsRoot common.Address EnsRoot common.Address
EnsApi string EnsApi string
@ -57,6 +57,7 @@ type Config struct {
NetworkId uint64 NetworkId uint64
SwapEnabled bool SwapEnabled bool
SyncEnabled bool SyncEnabled bool
PssEnabled bool
SwapApi string SwapApi string
Cors string Cors string
BzzAccount string BzzAccount string
@ -64,22 +65,23 @@ type Config struct {
} }
//create a default config with all parameters to set to defaults //create a default config with all parameters to set to defaults
func NewDefaultConfig() (self *Config) { func NewConfig() (self *Config) {
self = &Config{ self = &Config{
StoreParams: storage.NewDefaultStoreParams(), StoreParams: storage.NewDefaultStoreParams(),
ChunkerParams: storage.NewChunkerParams(), ChunkerParams: storage.NewChunkerParams(),
HiveParams: network.NewDefaultHiveParams(), HiveParams: network.NewHiveParams(),
SyncParams: network.NewDefaultSyncParams(), //SyncParams: network.NewDefaultSyncParams(),
Swap: swap.NewDefaultSwapParams(), Swap: swap.NewDefaultSwapParams(),
ListenAddr: DefaultHTTPListenAddr, ListenAddr: DefaultHTTPListenAddr,
Port: DefaultHTTPPort, Port: DefaultHTTPPort,
Path: node.DefaultDataDir(), Path: node.DefaultDataDir(),
EnsApi: node.DefaultIPCEndpoint("geth"), EnsApi: node.DefaultIPCEndpoint("geth"),
EnsRoot: ens.TestNetAddress, EnsRoot: ens.TestNetAddress,
NetworkId: network.NetworkId, NetworkId: network.NetworkID,
SwapEnabled: false, SwapEnabled: false,
SyncEnabled: true, SyncEnabled: true,
PssEnabled: true,
SwapApi: "", SwapApi: "",
BootNodes: "", BootNodes: "",
} }
@ -107,7 +109,7 @@ func (self *Config) Init(prvKey *ecdsa.PrivateKey) {
self.BzzKey = keyhex self.BzzKey = keyhex
self.Swap.Init(self.Contract, prvKey) self.Swap.Init(self.Contract, prvKey)
self.SyncParams.Init(self.Path) //self.SyncParams.Init(self.Path)
self.HiveParams.Init(self.Path) //self.HiveParams.Init(self.Path)
self.StoreParams.Init(self.Path) self.StoreParams.Init(self.Path)
} }

View file

@ -0,0 +1,16 @@
package storage
// implements CloudStore
// noop placeholder for netstore functionality
type Forwarder struct {
}
func (self *Forwarder) Store(chunk *Chunk) {
}
func (self *Forwarder) Retrieve(chunk *Chunk) {
}
func (self *Forwarder) Deliver(chunk *Chunk) {
}

View file

@ -33,11 +33,13 @@ import (
"github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/p2p/protocols"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/swarm/api" "github.com/ethereum/go-ethereum/swarm/api"
httpapi "github.com/ethereum/go-ethereum/swarm/api/http" httpapi "github.com/ethereum/go-ethereum/swarm/api/http"
"github.com/ethereum/go-ethereum/swarm/fuse" "github.com/ethereum/go-ethereum/swarm/fuse"
"github.com/ethereum/go-ethereum/swarm/network" "github.com/ethereum/go-ethereum/swarm/network"
"github.com/ethereum/go-ethereum/swarm/pss"
"github.com/ethereum/go-ethereum/swarm/storage" "github.com/ethereum/go-ethereum/swarm/storage"
) )
@ -46,18 +48,19 @@ type Swarm struct {
config *api.Config // swarm configuration config *api.Config // swarm configuration
api *api.Api // high level api layer (fs/manifest) api *api.Api // high level api layer (fs/manifest)
dns api.Resolver // DNS registrar dns api.Resolver // DNS registrar
dbAccess *network.DbAccess // access to local chunk db iterator and storage counter //dbAccess *network.DbAccess // access to local chunk db iterator and storage counter
storage storage.ChunkStore // internal access to storage, common interface to cloud storage backends storage storage.ChunkStore // internal access to storage, common interface to cloud storage backends
dpa *storage.DPA // distributed preimage archive, the local API to the storage with document level storage/retrieval support dpa *storage.DPA // distributed preimage archive, the local API to the storage with document level storage/retrieval support
depo network.StorageHandler // remote request handler, interface between bzz protocol and the storage //depo network.StorageHandler // remote request handler, interface between bzz protocol and the storage
cloud storage.CloudStore // procurement, cloud storage backend (can multi-cloud) cloud storage.CloudStore // procurement, cloud storage backend (can multi-cloud)
hive *network.Hive // the logistic manager bzz *network.Bzz // the logistic manager
backend chequebook.Backend // simple blockchain Backend backend chequebook.Backend // simple blockchain Backend
privateKey *ecdsa.PrivateKey privateKey *ecdsa.PrivateKey
corsString string corsString string
swapEnabled bool swapEnabled bool
lstore *storage.LocalStore // local store, needs to store for releasing resources after node stopped 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 sfs *fuse.SwarmFS // need this to cleanup all the active mounts on node exit
ps *pss.Pss
} }
type SwarmAPI struct { type SwarmAPI struct {
@ -76,7 +79,7 @@ func (self *Swarm) API() *SwarmAPI {
// creates a new swarm service instance // creates a new swarm service instance
// implements node.Service // implements node.Service
func NewSwarm(ctx *node.ServiceContext, backend chequebook.Backend, ensClient *ethclient.Client, config *api.Config, swapEnabled, syncEnabled bool, cors string) (self *Swarm, err error) { func NewSwarm(ctx *node.ServiceContext, backend chequebook.Backend, ensClient *ethclient.Client, config *api.Config, swapEnabled, syncEnabled bool, cors string, pssEnabled bool) (self *Swarm, err error) {
if bytes.Equal(common.FromHex(config.PublicKey), storage.ZeroKey) { if bytes.Equal(common.FromHex(config.PublicKey), storage.ZeroKey) {
return nil, fmt.Errorf("empty public key") return nil, fmt.Errorf("empty public key")
} }
@ -102,29 +105,26 @@ func NewSwarm(ctx *node.ServiceContext, backend chequebook.Backend, ensClient *e
// setup local store // setup local store
log.Debug(fmt.Sprintf("Set up local storage")) log.Debug(fmt.Sprintf("Set up local storage"))
self.dbAccess = network.NewDbAccess(self.lstore) kp := network.NewKadParams()
log.Debug(fmt.Sprintf("Set up local db access (iterator/counter)")) to := network.NewKademlia(
common.FromHex(config.BzzKey),
// set up the kademlia hive kp,
self.hive = network.NewHive(
common.HexToHash(self.config.BzzKey), // key to hive (kademlia base address)
config.HiveParams, // configuration parameters
swapEnabled, // SWAP enabled
syncEnabled, // syncronisation enabled
) )
log.Debug(fmt.Sprintf("Set up swarm network with Kademlia hive"))
// setup cloud storage backend config.HiveParams.Discovery = true
self.cloud = network.NewForwarder(self.hive)
log.Debug(fmt.Sprintf("-> set swarm forwarder as cloud storage backend"))
// setup cloud storage internal access layer // setup cloud storage internal access layer
self.cloud = &storage.Forwarder{}
self.storage = storage.NewNetStore(hash, self.lstore, self.cloud, config.StoreParams) self.storage = storage.NewNetStore(hash, self.lstore, self.cloud, config.StoreParams)
log.Debug(fmt.Sprintf("-> swarm net store shared access layer to Swarm Chunk Store")) log.Debug(fmt.Sprintf("-> swarm net store shared access layer to Swarm Chunk Store"))
nodeid := discover.PubkeyID(crypto.ToECDSAPub(common.FromHex(config.PublicKey)))
// set up Depo (storage handler = cloud storage access layer for incoming remote requests) addr := network.NewAddrFromNodeID(nodeid)
self.depo = network.NewDepo(hash, self.lstore, self.storage) bzzconfig := &network.BzzConfig{
log.Debug(fmt.Sprintf("-> REmote Access to CHunks")) OverlayAddr: common.FromHex(config.BzzKey),
UnderlayAddr: addr.UAddr,
HiveParams: config.HiveParams,
}
self.bzz = network.NewBzz(bzzconfig, to, nil)
// set up DPA, the cloud storage local access layer // set up DPA, the cloud storage local access layer
dpaChunkStore := storage.NewDpaChunkStore(self.lstore, self.storage) dpaChunkStore := storage.NewDpaChunkStore(self.lstore, self.storage)
@ -133,6 +133,15 @@ func NewSwarm(ctx *node.ServiceContext, backend chequebook.Backend, ensClient *e
self.dpa = storage.NewDPA(dpaChunkStore, self.config.ChunkerParams) self.dpa = storage.NewDPA(dpaChunkStore, self.config.ChunkerParams)
log.Debug(fmt.Sprintf("-> Content Store API")) log.Debug(fmt.Sprintf("-> Content Store API"))
// Pss = postal service over swarm (devp2p over bzz)
if pssEnabled {
pssparams := pss.NewPssParams(self.privateKey)
self.ps = pss.NewPss(to, self.dpa, pssparams)
if pss.IsActiveHandshake {
pss.SetHandshakeController(self.ps, pss.NewHandshakeParams())
}
}
// set up high level api // set up high level api
transactOpts := bind.NewKeyedTransactor(self.privateKey) transactOpts := bind.NewKeyedTransactor(self.privateKey)
@ -168,14 +177,11 @@ Start is called when the stack is started
*/ */
// implements the node.Service interface // implements the node.Service interface
func (self *Swarm) Start(srv *p2p.Server) error { func (self *Swarm) Start(srv *p2p.Server) error {
connectPeer := func(url string) error {
node, err := discover.ParseNode(url) // update uaddr to correct enode
if err != nil { newaddr := self.bzz.UpdateLocalAddr([]byte(srv.Self().String()))
return fmt.Errorf("invalid node URL: %v", err) log.Warn("Updated bzz local addr", "oaddr", fmt.Sprintf("%x", newaddr.OAddr), "uaddr", fmt.Sprintf("%x", newaddr.UAddr))
}
srv.AddPeer(node)
return nil
}
// set chequebook // set chequebook
if self.swapEnabled { if self.swapEnabled {
ctx := context.Background() // The initial setup has no deadline. ctx := context.Background() // The initial setup has no deadline.
@ -189,12 +195,18 @@ func (self *Swarm) Start(srv *p2p.Server) error {
} }
log.Warn(fmt.Sprintf("Starting Swarm service")) log.Warn(fmt.Sprintf("Starting Swarm service"))
self.hive.Start(
discover.PubkeyID(&srv.PrivateKey.PublicKey), err := self.bzz.Start(srv)
func() string { return srv.ListenAddr }, if err != nil {
connectPeer, log.Error("bzz failed", "err", err)
) return err
log.Info(fmt.Sprintf("Swarm network started on bzz address: %v", self.hive.Addr())) }
log.Info(fmt.Sprintf("Swarm network started on bzz address: %x", self.bzz.Hive.Overlay.BaseAddr()))
if self.ps != nil {
self.ps.Start(srv)
log.Info("Pss started")
}
self.dpa.Start() self.dpa.Start()
log.Debug(fmt.Sprintf("Swarm DPA started")) log.Debug(fmt.Sprintf("Swarm DPA started"))
@ -206,12 +218,13 @@ func (self *Swarm) Start(srv *p2p.Server) error {
Addr: addr, Addr: addr,
CorsString: self.corsString, CorsString: self.corsString,
}) })
log.Info(fmt.Sprintf("Swarm http proxy started on %v", addr)) }
log.Debug(fmt.Sprintf("Swarm http proxy started on port: %v", self.config.Port))
if self.corsString != "" { if self.corsString != "" {
log.Debug(fmt.Sprintf("Swarm http proxy started with corsdomain: %v", self.corsString)) log.Debug(fmt.Sprintf("Swarm http proxy started with corsdomain: %v", self.corsString))
} }
}
return nil return nil
} }
@ -220,7 +233,9 @@ func (self *Swarm) Start(srv *p2p.Server) error {
// stops all component services. // stops all component services.
func (self *Swarm) Stop() error { func (self *Swarm) Stop() error {
self.dpa.Stop() self.dpa.Stop()
err := self.hive.Stop() if self.ps != nil {
self.ps.Stop()
}
if ch := self.config.Swap.Chequebook(); ch != nil { if ch := self.config.Swap.Chequebook(); ch != nil {
ch.Stop() ch.Stop()
ch.Save() ch.Save()
@ -230,22 +245,37 @@ func (self *Swarm) Stop() error {
self.lstore.DbStore.Close() self.lstore.DbStore.Close()
} }
self.sfs.Stop() self.sfs.Stop()
return err return self.bzz.Stop()
} }
// implements the node.Service interface // implements the node.Service interface
func (self *Swarm) Protocols() []p2p.Protocol { func (self *Swarm) Protocols() (protos []p2p.Protocol) {
proto, err := network.Bzz(self.depo, self.backend, self.hive, self.dbAccess, self.config.Swap, self.config.SyncParams, self.config.NetworkId)
if err != nil { for _, p := range self.bzz.Protocols() {
return nil protos = append(protos, p)
} }
return []p2p.Protocol{proto}
if self.ps != nil {
for _, p := range self.ps.Protocols() {
protos = append(protos, p)
}
}
return
}
func (self *Swarm) RegisterPssProtocol(spec *protocols.Spec, targetprotocol *p2p.Protocol, options *pss.ProtocolParams) (*pss.Protocol, error) {
if !pss.IsActiveProtocol {
return nil, fmt.Errorf("Pss protocols not available (built with !nopssprotocol tag)")
}
topic := pss.ProtocolTopic(spec)
return pss.RegisterProtocol(self.ps, &topic, spec, targetprotocol, options)
} }
// implements node.Service // implements node.Service
// Apis returns the RPC Api descriptors the Swarm implementation offers // Apis returns the RPC Api descriptors the Swarm implementation offers
func (self *Swarm) APIs() []rpc.API { func (self *Swarm) APIs() []rpc.API {
return []rpc.API{
apis := []rpc.API{
// public APIs // public APIs
{ {
Namespace: "bzz", Namespace: "bzz",
@ -257,7 +287,7 @@ func (self *Swarm) APIs() []rpc.API {
{ {
Namespace: "bzz", Namespace: "bzz",
Version: "0.1", Version: "0.1",
Service: api.NewControl(self.api, self.hive), Service: api.NewControl(self.api, self.bzz.Hive),
Public: false, Public: false,
}, },
{ {
@ -288,6 +318,18 @@ func (self *Swarm) APIs() []rpc.API {
}, },
// {Namespace, Version, api.NewAdmin(self), false}, // {Namespace, Version, api.NewAdmin(self), false},
} }
for _, api := range self.bzz.APIs() {
apis = append(apis, api)
}
if self.ps != nil {
for _, api := range self.ps.APIs() {
apis = append(apis, api)
}
}
return apis
} }
func (self *Swarm) Api() *api.Api { func (self *Swarm) Api() *api.Api {
@ -301,7 +343,6 @@ func (self *Swarm) SetChequebook(ctx context.Context) error {
return err return err
} }
log.Info(fmt.Sprintf("new chequebook set (%v): saving config file, resetting all connections in the hive", self.config.Swap.Contract.Hex())) log.Info(fmt.Sprintf("new chequebook set (%v): saving config file, resetting all connections in the hive", self.config.Swap.Contract.Hex()))
self.hive.DropAll()
return nil return nil
} }
@ -313,10 +354,10 @@ func NewLocalSwarm(datadir, port string) (self *Swarm, err error) {
return return
} }
config := api.NewDefaultConfig() config := api.NewConfig()
config.Path = datadir config.Path = datadir
config.Init(prvKey)
config.Port = port config.Port = port
config.Init(prvKey)
dpa, err := storage.NewLocalDPA(datadir) dpa, err := storage.NewLocalDPA(datadir)
if err != nil { if err != nil {