From acda0d1be51ae66c3c08eddd237bfcd9ef7f6480 Mon Sep 17 00:00:00 2001 From: Victor Farazdagi Date: Mon, 29 Aug 2016 03:31:16 +0300 Subject: [PATCH] Adds Logout() binding --- src/gethdep.go | 18 ++++++++ src/gethdep_test.go | 46 +++++++++++++++++++ src/library.go | 20 ++++++++ .../ethereum/go-ethereum/whisper/whisper.go | 13 ++++++ 4 files changed, 97 insertions(+) diff --git a/src/gethdep.go b/src/gethdep.go index e18df8675..e6bf8f080 100644 --- a/src/gethdep.go +++ b/src/gethdep.go @@ -30,6 +30,7 @@ var ( ErrAccountToKeyMappingFailure = errors.New("cannot retreive a valid key for a given account") ErrUnlockCalled = errors.New("no need to unlock accounts, use Login() instead") ErrWhisperIdentityInjectionFailure = errors.New("failed to inject identity into Whisper") + ErrWhisperClearIdentitiesFailure = errors.New("failed to clear whisper identities") ) // createAccount creates an internal geth account @@ -143,6 +144,23 @@ func selectAccount(address, password string) error { return nil } +// logout clears whisper identities +func logout() error { + if currentNode == nil { + return ErrInvalidGethNode + } + if whisperService == nil { + return ErrInvalidWhisperService + } + + err := whisperService.ClearIdentities() + if err != nil { + return fmt.Errorf("%s: %v", ErrWhisperClearIdentitiesFailure, err) + } + + return nil +} + // unlockAccount unlocks an existing account for a certain duration and // inject the account as a whisper identity if the account was created as // a whisper enabled account diff --git a/src/gethdep_test.go b/src/gethdep_test.go index da926daa9..182fc17b6 100644 --- a/src/gethdep_test.go +++ b/src/gethdep_test.go @@ -127,6 +127,52 @@ func TestAccountSelect(t *testing.T) { } } +func TestAccountLogout(t *testing.T) { + + err := prepareTestNode() + if err != nil { + t.Error(err) + return + } + + var whisperInstance *whisper.Whisper + if err := currentNode.Service(&whisperInstance); err != nil { + t.Errorf("whisper service not running: %v", err) + } + + // create an account + address, pubKey, _, err := createAccount(newAccountPassword) + if err != nil { + t.Errorf("could not create account: %v", err) + return + } + + // make sure that identity doesn't exist (yet) in Whisper + if whisperInstance.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey))) { + t.Error("identity already present in whisper") + } + + // select/login + err = selectAccount(address, newAccountPassword) + if err != nil { + t.Errorf("Test failed: could not select account: %v", err) + return + } + if !whisperInstance.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey))) { + t.Error("identity not injected into whisper") + } + + err = logout() + if err != nil { + t.Errorf("cannot logout: %v", err) + } + + // now, logout and check if identity is removed indeed + if whisperInstance.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey))) { + t.Error("identity not cleared from whisper") + } +} + func TestWhisperMessaging(t *testing.T) { err := prepareTestNode() if err != nil { diff --git a/src/library.go b/src/library.go index 0729a2a1c..448ffa7fb 100644 --- a/src/library.go +++ b/src/library.go @@ -76,6 +76,26 @@ func Login(address, password *C.char) *C.char { return C.CString(string(outBytes)) } +//export Logout +func Logout() *C.char { + + // This is equivalent to clearing whisper identities + err := logout() + + errString := emptyError + if err != nil { + fmt.Fprintln(os.Stderr, err) + errString = err.Error() + } + + out := JSONError{ + Error: errString, + } + outBytes, _ := json.Marshal(&out) + + return C.CString(string(outBytes)) +} + //export UnlockAccount func UnlockAccount(address, password *C.char, seconds int) *C.char { diff --git a/src/vendor/github.com/ethereum/go-ethereum/whisper/whisper.go b/src/vendor/github.com/ethereum/go-ethereum/whisper/whisper.go index 987bc742f..68008ad8d 100644 --- a/src/vendor/github.com/ethereum/go-ethereum/whisper/whisper.go +++ b/src/vendor/github.com/ethereum/go-ethereum/whisper/whisper.go @@ -170,6 +170,19 @@ func (self *Whisper) InjectIdentity(key *ecdsa.PrivateKey) error { return nil } +// ClearIdentities clears the current whisper identities in memory +func (self *Whisper) ClearIdentities() error { + self.keysMu.Lock() + defer self.keysMu.Unlock() + + self.keys = make(map[string]*ecdsa.PrivateKey) + if len(self.keys) != 0 { + return fmt.Errorf("could not clear keys map") + } + + return nil +} + // Watch installs a new message handler to run in case a matching packet arrives // from the whisper network. func (self *Whisper) Watch(options Filter) int {