Initialize protocol when waku active (#1832)

This commit is contained in:
Andrea Maria Piana 2020-02-17 15:38:59 +01:00 committed by GitHub
parent 7ba20cb5a2
commit 141f917e7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 143 additions and 202 deletions

View File

@ -1 +1 @@
0.44.2
0.45.0

View File

@ -21,7 +21,6 @@ type StatusBackend interface {
// RestartNode() error // NOTE: Only used in tests
UpdateRootDataDir(datadir string)
UpdateMailservers(enodes []string) error
// SelectAccount(loginParams account.LoginParams) error
OpenAccounts() error
@ -49,7 +48,4 @@ type StatusBackend interface {
InjectChatAccount(chatKeyHex, encryptionKeyHex string) error // NOTE: Only used in lib and in tests
ExtractGroupMembershipSignatures(signaturePairs [][2]string) ([]string, error)
SignGroupMembership(content string) (string, error)
EnableInstallation(installationID string) error
DisableInstallation(installationID string) error
}

View File

@ -19,7 +19,6 @@ import (
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
gethnode "github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/status-im/status-go/account"
"github.com/status-im/status-go/appdatabase"
@ -54,6 +53,10 @@ var (
ErrWhisperClearIdentitiesFailure = errors.New("failed to clear whisper identities")
// ErrWhisperIdentityInjectionFailure injecting whisper identities has failed.
ErrWhisperIdentityInjectionFailure = errors.New("failed to inject identity into Whisper")
// ErrWakuClearIdentitiesFailure clearing whisper identities has failed.
ErrWakuClearIdentitiesFailure = errors.New("failed to clear waku identities")
// ErrWakuIdentityInjectionFailure injecting whisper identities has failed.
ErrWakuIdentityInjectionFailure = errors.New("failed to inject identity into waku")
// ErrUnsupportedRPCMethod is for methods not supported by the RPC interface
ErrUnsupportedRPCMethod = errors.New("method is unsupported by RPC interface")
// ErrRPCClientUnavailable is returned if an RPC client can't be retrieved.
@ -67,19 +70,19 @@ var _ StatusBackend = (*GethStatusBackend)(nil)
type GethStatusBackend struct {
mu sync.Mutex
// rootDataDir is the same for all networks.
rootDataDir string
appDB *sql.DB
statusNode *node.StatusNode
personalAPI *personal.PublicAPI
rpcFilters *rpcfilters.Service
multiaccountsDB *multiaccounts.Database
accountManager *account.GethManager
transactor *transactions.Transactor
connectionState connectionState
appState appState
selectedAccountShhKeyID string
log log.Logger
allowAllRPC bool // used only for tests, disables api method restrictions
rootDataDir string
appDB *sql.DB
statusNode *node.StatusNode
personalAPI *personal.PublicAPI
rpcFilters *rpcfilters.Service
multiaccountsDB *multiaccounts.Database
accountManager *account.GethManager
transactor *transactions.Transactor
connectionState connectionState
appState appState
selectedAccountKeyID string
log log.Logger
allowAllRPC bool // used only for tests, disables api method restrictions
}
// NewGethStatusBackend create a new GethStatusBackend instance
@ -116,9 +119,9 @@ func (b *GethStatusBackend) Transactor() *transactions.Transactor {
return b.transactor
}
// SelectedAccountShhKeyID returns a Whisper key ID of the selected chat key pair.
func (b *GethStatusBackend) SelectedAccountShhKeyID() string {
return b.selectedAccountShhKeyID
// SelectedAccountKeyID returns a Whisper key ID of the selected chat key pair.
func (b *GethStatusBackend) SelectedAccountKeyID() string {
return b.selectedAccountKeyID
}
// IsNodeRunning confirm that node is running
@ -806,10 +809,22 @@ func (b *GethStatusBackend) cleanupServices() error {
if err := whisperService.DeleteKeyPairs(); err != nil {
return fmt.Errorf("%s: %v", ErrWhisperClearIdentitiesFailure, err)
}
b.selectedAccountShhKeyID = ""
b.selectedAccountKeyID = ""
default:
return err
}
wakuService, err := b.statusNode.WakuService()
switch err {
case node.ErrServiceUnknown: // Waku was never registered
case nil:
if err := wakuService.DeleteKeyPairs(); err != nil {
return fmt.Errorf("%s: %v", ErrWakuClearIdentitiesFailure, err)
}
b.selectedAccountKeyID = ""
default:
return err
}
if b.statusNode.Config().WalletConfig.Enabled {
wallet, err := b.statusNode.WalletService()
switch err {
@ -878,7 +893,7 @@ func (b *GethStatusBackend) injectAccountIntoServices() error {
if err := whisperService.DeleteKeyPairs(); err != nil { // err is not possible; method return value is incorrect
return err
}
b.selectedAccountShhKeyID, err = whisperService.AddKeyPair(identity)
b.selectedAccountKeyID, err = whisperService.AddKeyPair(identity)
if err != nil {
return ErrWhisperIdentityInjectionFailure
}
@ -886,8 +901,24 @@ func (b *GethStatusBackend) injectAccountIntoServices() error {
return err
}
if whisperService != nil {
st, err := b.statusNode.ShhExtService()
wakuService, err := b.statusNode.WakuService()
switch err {
case node.ErrServiceUnknown: // Waku was never registered
case nil:
if err := wakuService.DeleteKeyPairs(); err != nil { // err is not possible; method return value is incorrect
return err
}
b.selectedAccountKeyID, err = wakuService.AddKeyPair(identity)
if err != nil {
return ErrWakuIdentityInjectionFailure
}
default:
return err
}
if wakuService != nil {
st, err := b.statusNode.WakuExtService()
if err != nil {
return err
}
@ -973,53 +1004,6 @@ func (b *GethStatusBackend) SignGroupMembership(content string) (string, error)
return crypto.SignStringAsHex(content, selectedChatAccount.AccountKey.PrivateKey)
}
// EnableInstallation enables an installation for multi-device sync.
func (b *GethStatusBackend) EnableInstallation(installationID string) error {
st, err := b.statusNode.ShhExtService()
if err != nil {
return err
}
if err := st.EnableInstallation(installationID); err != nil {
b.log.Error("error enabling installation", "err", err)
return err
}
return nil
}
// DisableInstallation disables an installation for multi-device sync.
func (b *GethStatusBackend) DisableInstallation(installationID string) error {
st, err := b.statusNode.ShhExtService()
if err != nil {
return err
}
if err := st.DisableInstallation(installationID); err != nil {
b.log.Error("error disabling installation", "err", err)
return err
}
return nil
}
// UpdateMailservers on ShhExtService.
func (b *GethStatusBackend) UpdateMailservers(enodes []string) error {
st, err := b.statusNode.ShhExtService()
if err != nil {
return err
}
nodes := make([]*enode.Node, len(enodes))
for i, rawurl := range enodes {
node, err := enode.ParseV4(rawurl)
if err != nil {
return err
}
nodes[i] = node
}
return st.UpdateMailservers(nodes)
}
// SignHash exposes vanilla ECDSA signing for signing a message for Swarm
func (b *GethStatusBackend) SignHash(hexEncodedHash string) (string, error) {
hash, err := hexutil.Decode(hexEncodedHash)

View File

@ -69,11 +69,11 @@ type nimbusStatusBackend struct {
multiaccountsDB *multiaccounts.Database
accountManager *account.GethManager
// transactor *transactions.Transactor
connectionState connectionState
appState appState
selectedAccountShhKeyID string
log log.Logger
allowAllRPC bool // used only for tests, disables api method restrictions
connectionState connectionState
appState appState
selectedAccountKeyID string
log log.Logger
allowAllRPC bool // used only for tests, disables api method restrictions
}
// NewNimbusStatusBackend create a new nimbusStatusBackend instance
@ -110,9 +110,9 @@ func (b *nimbusStatusBackend) AccountManager() *account.GethManager {
// return b.transactor
// }
// SelectedAccountShhKeyID returns a Whisper key ID of the selected chat key pair.
func (b *nimbusStatusBackend) SelectedAccountShhKeyID() string {
return b.selectedAccountShhKeyID
// SelectedAccountKeyID returns a Whisper key ID of the selected chat key pair.
func (b *nimbusStatusBackend) SelectedAccountKeyID() string {
return b.selectedAccountKeyID
}
// IsNodeRunning confirm that node is running
@ -809,7 +809,7 @@ func (b *nimbusStatusBackend) cleanupServices() error {
if err := whisperService.Whisper.DeleteKeyPairs(); err != nil {
return fmt.Errorf("%s: %v", ErrWhisperClearIdentitiesFailure, err)
}
b.selectedAccountShhKeyID = ""
b.selectedAccountKeyID = ""
default:
return err
}
@ -881,7 +881,7 @@ func (b *nimbusStatusBackend) injectAccountIntoServices() error {
if err := whisperService.Whisper.DeleteKeyPairs(); err != nil { // err is not possible; method return value is incorrect
return err
}
b.selectedAccountShhKeyID, err = whisperService.Whisper.AddKeyPair(identity)
b.selectedAccountKeyID, err = whisperService.Whisper.AddKeyPair(identity)
if err != nil {
return ErrWhisperIdentityInjectionFailure
}
@ -997,25 +997,6 @@ func (b *nimbusStatusBackend) DisableInstallation(installationID string) error {
return nil
}
// UpdateMailservers on ShhExtService.
func (b *nimbusStatusBackend) UpdateMailservers(enodes []string) error {
// TODO
return nil
// st, err := b.statusNode.ShhExtService()
// if err != nil {
// return err
// }
// nodes := make([]*enode.Node, len(enodes))
// for i, rawurl := range enodes {
// node, err := enode.ParseV4(rawurl)
// if err != nil {
// return err
// }
// nodes[i] = node
// }
// return st.UpdateMailservers(nodes)
}
// SignHash exposes vanilla ECDSA signing for signing a message for Swarm
func (b *nimbusStatusBackend) SignHash(hexEncodedHash string) (string, error) {
hash, err := types.DecodeHex(hexEncodedHash)

View File

@ -88,42 +88,6 @@ func SignGroupMembership(content *C.char) *C.char {
return C.CString(string(data))
}
// EnableInstallation enables an installation for multi-device sync.
//export EnableInstallation
func EnableInstallation(installationID *C.char) *C.char {
err := statusBackend.EnableInstallation(C.GoString(installationID))
if err != nil {
return makeJSONResponse(err)
}
data, err := json.Marshal(struct {
Response string `json:"response"`
}{Response: "ok"})
if err != nil {
return makeJSONResponse(err)
}
return C.CString(string(data))
}
// DisableInstallation disables an installation for multi-device sync.
//export DisableInstallation
func DisableInstallation(installationID *C.char) *C.char {
err := statusBackend.DisableInstallation(C.GoString(installationID))
if err != nil {
return makeJSONResponse(err)
}
data, err := json.Marshal(struct {
Response string `json:"response"`
}{Response: "ok"})
if err != nil {
return makeJSONResponse(err)
}
return C.CString(string(data))
}
//ValidateNodeConfig validates config for status node
//export ValidateNodeConfig
func ValidateNodeConfig(configJSON *C.char) *C.char {
@ -579,18 +543,6 @@ func makeJSONResponse(err error) *C.char {
return C.CString(string(outBytes))
}
// UpdateMailservers updates mail servers in status backend.
//export UpdateMailservers
func UpdateMailservers(data *C.char) *C.char {
var enodes []string
err := json.Unmarshal([]byte(C.GoString(data)), &enodes)
if err != nil {
return makeJSONResponse(err)
}
err = statusBackend.UpdateMailservers(enodes)
return makeJSONResponse(err)
}
// AddPeer adds an enode as a peer.
//export AddPeer
func AddPeer(enode *C.char) *C.char {

View File

@ -100,40 +100,6 @@ func SignGroupMembership(content string) string {
return string(data)
}
// EnableInstallation enables an installation for multi-device sync.
func EnableInstallation(installationID string) string {
err := statusBackend.EnableInstallation(installationID)
if err != nil {
return makeJSONResponse(err)
}
data, err := json.Marshal(struct {
Response string `json:"response"`
}{Response: "ok"})
if err != nil {
return makeJSONResponse(err)
}
return string(data)
}
// DisableInstallation disables an installation for multi-device sync.
func DisableInstallation(installationID string) string {
err := statusBackend.DisableInstallation(installationID)
if err != nil {
return makeJSONResponse(err)
}
data, err := json.Marshal(struct {
Response string `json:"response"`
}{Response: "ok"})
if err != nil {
return makeJSONResponse(err)
}
return string(data)
}
// ValidateNodeConfig validates config for the Status node.
func ValidateNodeConfig(configJSON string) string {
var resp APIDetailedResponse
@ -608,18 +574,6 @@ func makeJSONResponse(err error) string {
return string(outBytes)
}
// UpdateMailservers updates mail servers in status backend.
//export UpdateMailservers
func UpdateMailservers(data string) string {
var enodes []string
err := json.Unmarshal([]byte(data), &enodes)
if err != nil {
return makeJSONResponse(err)
}
err = statusBackend.UpdateMailservers(enodes)
return makeJSONResponse(err)
}
// GetNodesFromContract returns a list of nodes from a given contract
//export GetNodesFromContract
func GetNodesFromContract(rpcEndpoint string, contractAddress string) string {

View File

@ -385,6 +385,22 @@ func activateWakuService(stack *node.Node, config *params.NodeConfig, db *leveld
return
}
// Register Whisper eth-node bridge
err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
var ethnode *nodebridge.NodeService
if err := ctx.Service(&ethnode); err != nil {
return nil, err
}
w, err := ethnode.Node.GetWaku(ctx)
if err != nil {
return nil, err
}
return &nodebridge.WakuService{Waku: w}, nil
})
if err != nil {
return
}
// TODO(dshulyak) add a config option to enable it by default, but disable if app is started from statusd
return stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
var ethnode *nodebridge.NodeService

View File

@ -9,6 +9,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/rlp"
"github.com/status-im/status-go/eth-node/types"
@ -392,6 +393,18 @@ func (api *PublicAPI) SyncDevices(ctx context.Context, name, picture string) err
return api.service.messenger.SyncDevices(ctx, name, picture)
}
func (api *PublicAPI) UpdateMailservers(enodes []string) error {
nodes := make([]*enode.Node, len(enodes))
for i, rawurl := range enodes {
node, err := enode.ParseV4(rawurl)
if err != nil {
return err
}
nodes[i] = node
}
return api.service.UpdateMailservers(nodes)
}
// Echo is a method for testing purposes.
func (api *PublicAPI) Echo(ctx context.Context, message string) (string, error) {
return message, nil

View File

@ -0,0 +1,45 @@
package nodebridge
import (
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rpc"
"github.com/status-im/status-go/eth-node/types"
)
// Make sure that WakuService implements node.Service interface.
var _ node.Service = (*WakuService)(nil)
type WakuService struct {
Waku types.Waku
}
// Protocols returns a new protocols list. In this case, there are none.
func (w *WakuService) Protocols() []p2p.Protocol {
return []p2p.Protocol{}
}
// APIs returns a list of new APIs.
func (w *WakuService) APIs() []rpc.API {
return []rpc.API{
{
Namespace: "status",
Version: "1.0",
Service: w.Waku,
Public: false,
},
}
}
// Start is run when a service is started.
// It does nothing in this case but is required by `node.Service` interface.
func (w *WakuService) Start(server *p2p.Server) error {
return nil
}
// Stop is run when a service is stopped.
// It does nothing in this case but is required by `node.Service` interface.
func (w *WakuService) Stop() error {
return nil
}

View File

@ -191,16 +191,16 @@ func (s *WhisperTestSuite) TestSelectedAccountOnRestart() {
s.NoError(err)
selectedChatPubKey1 := types.EncodeHex(crypto.FromECDSAPub(&selectedChatAccount1.AccountKey.PrivateKey.PublicKey))
s.Equal(selectedChatPubKey1, accountInfo1.ChatPubKey)
s.True(whisperService.HasKeyPair(s.Backend.SelectedAccountShhKeyID()), "identity not injected into whisper")
s.True(whisperService.HasKeyPair(s.Backend.SelectedAccountKeyID()), "identity not injected into whisper")
// select another account, make sure that previous account is wiped out from Whisper cache
previousKeyID := s.Backend.SelectedAccountShhKeyID()
previousKeyID := s.Backend.SelectedAccountKeyID()
s.NoError(s.Backend.SelectAccount(buildLoginParams(accountInfo2.WalletAddress, accountInfo2.ChatAddress, TestConfig.Account2.Password)))
selectedChatAccount2, err := s.Backend.AccountManager().SelectedChatAccount()
s.NoError(err)
selectedChatPubKey2 := types.EncodeHex(crypto.FromECDSAPub(&selectedChatAccount2.AccountKey.PrivateKey.PublicKey))
s.Equal(selectedChatPubKey2, accountInfo2.ChatPubKey)
s.True(whisperService.HasKeyPair(s.Backend.SelectedAccountShhKeyID()), "identity not injected into whisper")
s.True(whisperService.HasKeyPair(s.Backend.SelectedAccountKeyID()), "identity not injected into whisper")
s.False(whisperService.HasKeyPair(previousKeyID), "identity should be removed, but it is still present in whisper")
// stop node (and all of its sub-protocols)
@ -224,7 +224,7 @@ func (s *WhisperTestSuite) TestSelectedAccountOnRestart() {
// make sure that Whisper gets identity re-injected
whisperService = s.WhisperService()
s.True(whisperService.HasKeyPair(s.Backend.SelectedAccountShhKeyID()), "identity not injected into whisper")
s.True(whisperService.HasKeyPair(s.Backend.SelectedAccountKeyID()), "identity not injected into whisper")
s.False(whisperService.HasKeyPair(previousKeyID), "identity should not be present, but it is still present in whisper")
// now restart node using RestartNode() method, and make sure that account is still available
@ -232,14 +232,14 @@ func (s *WhisperTestSuite) TestSelectedAccountOnRestart() {
defer s.StopTestBackend()
whisperService = s.WhisperService()
s.True(whisperService.HasKeyPair(s.Backend.SelectedAccountShhKeyID()), "identity not injected into whisper")
s.True(whisperService.HasKeyPair(s.Backend.SelectedAccountKeyID()), "identity not injected into whisper")
s.False(whisperService.HasKeyPair(previousKeyID), "identity should not be present, but it is still present in whisper")
// now logout, and make sure that on restart no account is selected (i.e. logout works properly)
s.NoError(s.Backend.Logout())
s.RestartTestNode()
whisperService = s.WhisperService()
s.False(whisperService.HasKeyPair(s.Backend.SelectedAccountShhKeyID()), "identity not injected into whisper")
s.False(whisperService.HasKeyPair(s.Backend.SelectedAccountKeyID()), "identity not injected into whisper")
s.False(whisperService.HasKeyPair(previousKeyID), "identity should not be present, but it is still present in whisper")
selectedWalletAccount, err = s.Backend.AccountManager().MainAccountAddress()