Skip to content

Commit

Permalink
swarm: add integration with swarm service
Browse files Browse the repository at this point in the history
  • Loading branch information
mchusovlianov authored and farazdagi committed Feb 27, 2017
1 parent 0d64eda commit c46a0b0
Show file tree
Hide file tree
Showing 8 changed files with 858 additions and 214 deletions.
1 change: 1 addition & 0 deletions data/testfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
swarm test
27 changes: 27 additions & 0 deletions geth/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,15 @@ func SelectAccount(address, password string) error {
return ErrWhisperIdentityInjectionFailure
}

swarmService, err := nodeManager.SwarmService()
if err != nil {
return err
}

if err := swarmService.RunSwarmNode(accountKey.PrivateKey); err != nil {
return ErrSwarmIdentityInjectionFailure
}

// persist account key for easier recovery of currently selected key
subAccounts, err := findSubAccounts(accountKey.ExtendedKey, accountKey.SubAccountIndex)
if err != nil {
Expand Down Expand Up @@ -185,6 +194,15 @@ func ReSelectAccount() error {
return ErrWhisperIdentityInjectionFailure
}

swarmService, err := nodeManager.SwarmService()
if err != nil {
return err
}

if err := swarmService.RunSwarmNode(selectedAccount.AccountKey.PrivateKey); err != nil {
return ErrSwarmIdentityInjectionFailure
}

return nil
}

Expand All @@ -201,6 +219,15 @@ func Logout() error {
return fmt.Errorf("%s: %v", ErrWhisperClearIdentitiesFailure, err)
}

swarmService, err := nodeManager.SwarmService()
if err != nil {
return err
}

if err := swarmService.StopSwarmNode(); err != nil {
return err
}

nodeManager.SelectedAccount = nil

return nil
Expand Down
48 changes: 37 additions & 11 deletions geth/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ func init() {

// node-related errors
var (
ErrEthServiceRegistrationFailure = errors.New("failed to register the Ethereum service")
ErrSshServiceRegistrationFailure = errors.New("failed to register the Whisper service")
ErrLightEthRegistrationFailure = errors.New("failed to register the LES service")
ErrEthServiceRegistrationFailure = errors.New("failed to register the Ethereum service")
ErrSshServiceRegistrationFailure = errors.New("failed to register the Whisper service")
ErrSwarmServiceRegistrationFailure = errors.New("failed to register the Swarm service")
ErrLightEthRegistrationFailure = errors.New("failed to register the LES service")
)

// NodeConfig stores configuration options for a node
Expand All @@ -92,10 +93,11 @@ type NodeConfig struct {

// Node represents running node (serves as a wrapper around P2P node)
type Node struct {
config *NodeConfig // configuration used to create Status node
geth *node.Node // reference to the running Geth node
gethConfig *node.Config // configuration used to create P2P node
started chan struct{} // channel to wait for node to start
config *NodeConfig // configuration used to create Status node
geth *node.Node // reference to the running Geth node
gethConfig *node.Config // configuration used to create P2P node
started chan struct{} // channel to wait for node to start
swarmService *SwarmService
}

// Inited checks whether status node has been properly initialized
Expand Down Expand Up @@ -156,11 +158,18 @@ func MakeNode(config *NodeConfig) *Node {
Fatalf(fmt.Errorf("%v: %v", ErrSshServiceRegistrationFailure, err))
}

// start Swarm service
swarmService, err := activateSwarmService(stack)
if err != nil {
Fatalf(fmt.Errorf("%v: %v", ErrSwarmServiceRegistrationFailure, err))
}

return &Node{
geth: stack,
gethConfig: stackConfig,
started: make(chan struct{}),
config: config,
geth: stack,
gethConfig: stackConfig,
started: make(chan struct{}),
config: config,
swarmService: swarmService,
}
}

Expand Down Expand Up @@ -215,6 +224,23 @@ func activateShhService(stack *node.Node) error {
return nil
}

// activateSwarmService configures Swarm and adds it to the given node.
func activateSwarmService(stack *node.Node) (*SwarmService, error) {
swarmService, err := newSwarmService(stack)
if err != nil {
return nil, err
}

serviceConstructor := func(ctx *node.ServiceContext) (node.Service, error) {
return swarmService.swarm, nil
}
if err := stack.Register(serviceConstructor); err != nil {
return nil, err
}

return swarmService, nil
}

// makeIPCPath returns IPC-RPC filename
func makeIPCPath(dataDir string, ipcEnabled bool) string {
if !ipcEnabled {
Expand Down
19 changes: 19 additions & 0 deletions geth/node_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/swarm"
whisper "github.com/ethereum/go-ethereum/whisper/whisperv2"
)

Expand All @@ -42,6 +43,7 @@ type NodeServiceStack struct {
whisperService *whisper.Whisper // Whisper service
rpcClient *rpc.Client // RPC client
jailedRequestQueue *JailedRequestQueue // bridge via which jail notifies node of incoming requests
swarm *swarm.Swarm // swarm service
}

var (
Expand Down Expand Up @@ -113,6 +115,9 @@ func (m *NodeManager) RunNode() {
if err := m.node.geth.Service(&m.services.lightEthereum); err != nil {
glog.V(logger.Warn).Infoln("cannot get light ethereum service:", err)
}
if err := m.node.geth.Service(&m.services.swarm); err != nil {
glog.V(logger.Warn).Infoln("cannot get swarm service:", err)
}

// setup handlers
lightEthereum, err := m.LightEthereumService()
Expand Down Expand Up @@ -177,6 +182,7 @@ func (m *NodeManager) StopNode() error {

m.node.geth.Stop()
m.node.started = make(chan struct{})

return nil
}

Expand Down Expand Up @@ -419,3 +425,16 @@ func (k *SelectedExtKey) Hex() string {

return k.Address.Hex()
}

// SwarmService exposes Swarm service
func (m *NodeManager) SwarmService() (*SwarmService, error) {
if m == nil || !m.NodeInited() {
return nil, ErrInvalidGethNode
}

if m.node == nil || m.node.swarmService == nil {
return nil, ErrInvalidSwarmService
}

return m.node.swarmService, nil
}
95 changes: 95 additions & 0 deletions geth/swarm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package geth

import (
"crypto/ecdsa"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/swarm"
bzzapi "github.com/ethereum/go-ethereum/swarm/api"
"path/filepath"
)

var (
ErrInvalidSwarmService = errors.New("swarm service is unavailable")
ErrSwarmIdentityInjectionFailure = errors.New("failed to inject identity into Swarm")
)

// Service for managing swarm instance
type SwarmService struct {
instanceDir string
httpEndpoint string
swarm *swarm.Swarm
privateKey *ecdsa.PrivateKey
}

func newSwarmService(stack *node.Node) (*SwarmService, error) {
service := &SwarmService{
instanceDir: filepath.Join(stack.InstanceDir(), "swarm"),
httpEndpoint: fmt.Sprintf("http://%s", stack.HTTPEndpoint()),
}

var err error
service.swarm, err = service.newSwarmNode(nil)

return service, err
}

// activateSwarmService configures and registers the SwarmService with a given node.
func (s *SwarmService) newSwarmNode(prvkey *ecdsa.PrivateKey) (*swarm.Swarm, error) {
if prvkey == nil {
prvkey, _ = crypto.GenerateKey()
}

chbookaddr := common.Address{}

networkId := uint64(1)
if UseTestnet {
networkId = 3
}

bzzconfig, err := bzzapi.NewConfig(s.instanceDir, chbookaddr, prvkey, networkId)
if err != nil {
return nil, fmt.Errorf("%v: %v", err, err)
}

var client *ethclient.Client
client, err = ethclient.Dial(s.httpEndpoint)
if err != nil {
return nil, fmt.Errorf("Can't connect: %v", err)
}

return swarm.NewSwarm(nil, client, bzzconfig, false, true, "")
}

// Run swarm node on with specified private key
func (s *SwarmService) RunSwarmNode(prvkey *ecdsa.PrivateKey) error {
nodeManager := NodeManagerInstance()
p2p := nodeManager.node.geth.Server()

// stop old swarm instance
err := s.StopSwarmNode()
if err != nil {
return err
}

sw, err := s.newSwarmNode(prvkey)
if err != nil {
return err
}

*s.swarm = *sw
return s.swarm.Start(p2p)
}

// Stop current running swarm node
func (s *SwarmService) StopSwarmNode() error {
err := s.swarm.Stop()
if err != nil {
return err
}
return nil
}
Loading

0 comments on commit c46a0b0

Please # to comment.