Merge pull request #129 from status-im/feature/whisper-ver5
Feature: whisper ver5 support
This commit is contained in:
commit
01a1550511
|
@ -6,7 +6,6 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv2"
|
||||
"github.com/status-im/status-go/geth"
|
||||
"github.com/status-im/status-go/geth/jail"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
|
@ -296,43 +295,6 @@ func AddPeer(url *C.char) *C.char {
|
|||
return C.CString(string(outBytes))
|
||||
}
|
||||
|
||||
//export AddWhisperFilter
|
||||
func AddWhisperFilter(filterJson *C.char) *C.char {
|
||||
|
||||
var id int
|
||||
var filter whisper.NewFilterArgs
|
||||
|
||||
err := json.Unmarshal([]byte(C.GoString(filterJson)), &filter)
|
||||
if err == nil {
|
||||
id = geth.AddWhisperFilter(filter)
|
||||
}
|
||||
|
||||
errString := ""
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
errString = err.Error()
|
||||
}
|
||||
|
||||
out := geth.AddWhisperFilterResult{
|
||||
Id: id,
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, _ := json.Marshal(&out)
|
||||
|
||||
return C.CString(string(outBytes))
|
||||
|
||||
}
|
||||
|
||||
//export RemoveWhisperFilter
|
||||
func RemoveWhisperFilter(idFilter int) {
|
||||
geth.RemoveWhisperFilter(idFilter)
|
||||
}
|
||||
|
||||
//export ClearWhisperFilters
|
||||
func ClearWhisperFilters() {
|
||||
geth.ClearWhisperFilters()
|
||||
}
|
||||
|
||||
func makeJSONErrorResponse(err error) *C.char {
|
||||
errString := ""
|
||||
if err != nil {
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/les/status"
|
||||
gethparams "github.com/ethereum/go-ethereum/params"
|
||||
"github.com/status-im/status-go/geth"
|
||||
|
@ -230,7 +229,7 @@ func testStopResumeNode(t *testing.T) bool {
|
|||
t.Logf("account created: {address: %s, key: %s}", address1, pubKey1)
|
||||
|
||||
// make sure that identity is not (yet injected)
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if whisperService.HasIdentity(pubKey1) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
|
||||
|
@ -247,7 +246,7 @@ func testStopResumeNode(t *testing.T) bool {
|
|||
t.Errorf("could not select account: %v", err)
|
||||
return false
|
||||
}
|
||||
if !whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if !whisperService.HasIdentity(pubKey1) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
|
||||
|
@ -296,7 +295,7 @@ func testStopResumeNode(t *testing.T) bool {
|
|||
if err != nil {
|
||||
t.Errorf("whisper service not running: %v", err)
|
||||
}
|
||||
if !whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if !whisperService.HasIdentity(pubKey1) {
|
||||
t.Errorf("identity evicted from whisper on node restart: %v", err)
|
||||
}
|
||||
|
||||
|
@ -581,7 +580,7 @@ func testRecoverAccount(t *testing.T) bool {
|
|||
}
|
||||
|
||||
// make sure that identity is not (yet injected)
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKeyCheck))) {
|
||||
if whisperService.HasIdentity(pubKeyCheck) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
err = geth.SelectAccount(addressCheck, testConfig.Account1.Password)
|
||||
|
@ -589,7 +588,7 @@ func testRecoverAccount(t *testing.T) bool {
|
|||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return false
|
||||
}
|
||||
if !whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKeyCheck))) {
|
||||
if !whisperService.HasIdentity(pubKeyCheck) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
|
||||
|
@ -619,7 +618,7 @@ func testAccountSelect(t *testing.T) bool {
|
|||
t.Logf("Account created: {address: %s, key: %s}", address2, pubKey2)
|
||||
|
||||
// make sure that identity is not (yet injected)
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if whisperService.HasIdentity(pubKey1) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
|
||||
|
@ -649,12 +648,12 @@ func testAccountSelect(t *testing.T) bool {
|
|||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return false
|
||||
}
|
||||
if !whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if !whisperService.HasIdentity(pubKey1) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
|
||||
// select another account, make sure that previous account is wiped out from Whisper cache
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey2))) {
|
||||
if whisperService.HasIdentity(pubKey2) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
|
||||
|
@ -670,10 +669,10 @@ func testAccountSelect(t *testing.T) bool {
|
|||
t.Errorf("Test failed: could not select account: %v", loginResponse.Error)
|
||||
return false
|
||||
}
|
||||
if !whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey2))) {
|
||||
if !whisperService.HasIdentity(pubKey2) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if whisperService.HasIdentity(pubKey1) {
|
||||
t.Error("identity should be removed, but it is still present in whisper")
|
||||
}
|
||||
|
||||
|
@ -695,7 +694,7 @@ func testAccountLogout(t *testing.T) bool {
|
|||
}
|
||||
|
||||
// make sure that identity doesn't exist (yet) in Whisper
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey))) {
|
||||
if whisperService.HasIdentity(pubKey) {
|
||||
t.Error("identity already present in whisper")
|
||||
return false
|
||||
}
|
||||
|
@ -706,7 +705,7 @@ func testAccountLogout(t *testing.T) bool {
|
|||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return false
|
||||
}
|
||||
if !whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey))) {
|
||||
if !whisperService.HasIdentity(pubKey) {
|
||||
t.Error("identity not injected into whisper")
|
||||
return false
|
||||
}
|
||||
|
@ -725,7 +724,7 @@ func testAccountLogout(t *testing.T) bool {
|
|||
}
|
||||
|
||||
// now, logout and check if identity is removed indeed
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey))) {
|
||||
if whisperService.HasIdentity(pubKey) {
|
||||
t.Error("identity not cleared from whisper")
|
||||
return false
|
||||
}
|
||||
|
@ -1314,12 +1313,22 @@ func startTestNode(t *testing.T) <-chan struct{} {
|
|||
}
|
||||
|
||||
// import test account (with test ether on it)
|
||||
dst := filepath.Join(geth.TestDataDir, "testnet", "keystore", "test-account.pk")
|
||||
if _, err := os.Stat(dst); os.IsNotExist(err) {
|
||||
err = geth.CopyFile(dst, filepath.Join(geth.RootDir, "data", "test-account.pk"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
importTestAccount := func(accountFile string) error {
|
||||
dst := filepath.Join(geth.TestDataDir, "keystore", accountFile)
|
||||
if _, err := os.Stat(dst); os.IsNotExist(err) {
|
||||
err = geth.CopyFile(dst, filepath.Join(geth.RootDir, "data", accountFile))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
if err := importTestAccount("test-account1.pk"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := importTestAccount("test-account2.pk"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
waitForNodeStart := make(chan struct{}, 1)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"address":"65c01586aa0ce152835c788ace665e91ab3527b8","crypto":{"cipher":"aes-128-ctr","ciphertext":"26155f5c315492ccb40f24aeb34ff6bfbdbdcb7402b9e7bb558fa4c936be51ff","cipherparams":{"iv":"1d9b3043b59c3995c410f82cd96bfe05"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":4096,"p":6,"r":8,"salt":"4bb6d2080121e7ecc8b3dcba95cd0031cf3b36174612247c14486266580ed4b8"},"mac":"cc8f209d9128a4e9a836c691324e1459d4d3d2a2b0627cf94e99a7e8b305b6dc"},"id":"756c215e-d3af-435d-8fcf-39eb62d9a590","version":3,"whisperenabled":true,"extendedkey":{"cipher":"aes-128-ctr","ciphertext":"dd5cc47cde930bdb9a1625ff2efd230bac9a52e9d7e220aa699c017c4ac1ff645765a721ac6f4143ffa551ecf775f20b25e7cd5d3856ef59e7f31d407bf2d0404f2323919101c37c94952fb8462d4281a92b005e9f81a6dd1aff2f4eb15cb4c6a56df907c9591503c7d89b0cea08cb","cipherparams":{"iv":"f66b414b6678816bc3e5bb214624b4f7"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":4096,"p":6,"r":8,"salt":"094ba4f65bac68f8a9807871187dd915540013a0792bf3d11d019ae3cea7d7c0"},"mac":"2e2979943a75cff762480c26b3daff0fac78cdf12e0ed791e6a1321f3ed8fc91"},"subaccountindex":0}
|
|
@ -9,7 +9,7 @@
|
|||
"Password": "asdfasdf"
|
||||
},
|
||||
"Account2": {
|
||||
"Address": "0xadd4d1d02e71c7360c53296968e59d57fd15e2ba",
|
||||
"Address": "0x65c01586aa0ce152835c788ace665e91ab3527b8",
|
||||
"Password": "asdfasdf"
|
||||
}
|
||||
}
|
|
@ -5,8 +5,6 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/status-im/status-go/geth"
|
||||
)
|
||||
|
||||
|
@ -289,7 +287,7 @@ func TestAccountsRecoverAccount(t *testing.T) {
|
|||
}
|
||||
|
||||
// make sure that identity is not (yet injected)
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKeyCheck))) {
|
||||
if whisperService.HasIdentity(pubKeyCheck) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
err = geth.SelectAccount(addressCheck, testConfig.Account1.Password)
|
||||
|
@ -297,7 +295,7 @@ func TestAccountsRecoverAccount(t *testing.T) {
|
|||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
}
|
||||
if !whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKeyCheck))) {
|
||||
if !whisperService.HasIdentity(pubKeyCheck) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
}
|
||||
|
@ -332,7 +330,7 @@ func TestAccountSelect(t *testing.T) {
|
|||
t.Logf("Account created: {address: %s, key: %s}", address2, pubKey2)
|
||||
|
||||
// make sure that identity is not (yet injected)
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if whisperService.HasIdentity(pubKey1) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
|
||||
|
@ -347,12 +345,12 @@ func TestAccountSelect(t *testing.T) {
|
|||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
}
|
||||
if !whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if !whisperService.HasIdentity(pubKey1) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
|
||||
// select another account, make sure that previous account is wiped out from Whisper cache
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey2))) {
|
||||
if whisperService.HasIdentity(pubKey2) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
err = geth.SelectAccount(address2, testConfig.Account1.Password)
|
||||
|
@ -360,10 +358,10 @@ func TestAccountSelect(t *testing.T) {
|
|||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
}
|
||||
if !whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey2))) {
|
||||
if !whisperService.HasIdentity(pubKey2) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if whisperService.HasIdentity(pubKey1) {
|
||||
t.Error("identity should be removed, but it is still present in whisper")
|
||||
}
|
||||
}
|
||||
|
@ -389,7 +387,7 @@ func TestAccountsLogout(t *testing.T) {
|
|||
}
|
||||
|
||||
// make sure that identity doesn't exist (yet) in Whisper
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey))) {
|
||||
if whisperService.HasIdentity(pubKey) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
|
||||
|
@ -399,7 +397,7 @@ func TestAccountsLogout(t *testing.T) {
|
|||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
}
|
||||
if !whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey))) {
|
||||
if !whisperService.HasIdentity(pubKey) {
|
||||
t.Error("identity not injected into whisper")
|
||||
}
|
||||
|
||||
|
@ -409,7 +407,7 @@ func TestAccountsLogout(t *testing.T) {
|
|||
}
|
||||
|
||||
// now, logout and check if identity is removed indeed
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey))) {
|
||||
if whisperService.HasIdentity(pubKey) {
|
||||
t.Error("identity not cleared from whisper")
|
||||
}
|
||||
}
|
||||
|
@ -442,7 +440,7 @@ func TestAccountsSelectedAccountOnNodeRestart(t *testing.T) {
|
|||
t.Logf("account2 created: {address: %s, key: %s}", address2, pubKey2)
|
||||
|
||||
// make sure that identity is not (yet injected)
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if whisperService.HasIdentity(pubKey1) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
|
||||
|
@ -463,12 +461,12 @@ func TestAccountsSelectedAccountOnNodeRestart(t *testing.T) {
|
|||
t.Errorf("could not select account: %v", err)
|
||||
return
|
||||
}
|
||||
if !whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if !whisperService.HasIdentity(pubKey1) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
|
||||
// select another account, make sure that previous account is wiped out from Whisper cache
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey2))) {
|
||||
if whisperService.HasIdentity(pubKey2) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
err = geth.SelectAccount(address2, testConfig.Account1.Password)
|
||||
|
@ -476,10 +474,10 @@ func TestAccountsSelectedAccountOnNodeRestart(t *testing.T) {
|
|||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
}
|
||||
if !whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey2))) {
|
||||
if !whisperService.HasIdentity(pubKey2) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if whisperService.HasIdentity(pubKey1) {
|
||||
t.Error("identity should be removed, but it is still present in whisper")
|
||||
}
|
||||
|
||||
|
@ -520,10 +518,10 @@ func TestAccountsSelectedAccountOnNodeRestart(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Errorf("whisper service not running: %v", err)
|
||||
}
|
||||
if !whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey2))) {
|
||||
if !whisperService.HasIdentity(pubKey2) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if whisperService.HasIdentity(pubKey1) {
|
||||
t.Error("identity should not be present, but it is still present in whisper")
|
||||
}
|
||||
}
|
||||
|
@ -552,7 +550,7 @@ func TestAccountsNodeRestartWithNoSelectedAccount(t *testing.T) {
|
|||
t.Logf("account1 created: {address: %s, key: %s}", address1, pubKey1)
|
||||
|
||||
// make sure that identity is not present
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if whisperService.HasIdentity(pubKey1) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
|
||||
|
@ -591,7 +589,7 @@ func TestAccountsNodeRestartWithNoSelectedAccount(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Errorf("whisper service not running: %v", err)
|
||||
}
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
if whisperService.HasIdentity(pubKey1) {
|
||||
t.Error("identity should not be present, but it is present in whisper")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,19 +10,23 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
|
||||
"github.com/status-im/status-go/geth"
|
||||
"github.com/status-im/status-go/geth/jail"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
const (
|
||||
CHAT_ID_INIT = "CHAT_ID_INIT_TEST"
|
||||
CHAT_ID_CALL = "CHAT_ID_CALL_TEST"
|
||||
CHAT_ID_SEND = "CHAT_ID_CALL_SEND"
|
||||
CHAT_ID_NON_EXISTENT = "CHAT_IDNON_EXISTENT"
|
||||
|
||||
TESTDATA_STATUS_JS = "testdata/status.js"
|
||||
TESTDATA_TX_SEND_JS = "testdata/tx-send/"
|
||||
whisperMessage1 = `test message 1 (K1 -> K2, signed+encrypted, from us)`
|
||||
whisperMessage2 = `test message 2 (K1 -> K1, signed+encrypted to ourselves)`
|
||||
whisperMessage3 = `test message 3 (K1 -> "", signed broadcast)`
|
||||
whisperMessage4 = `test message 4 ("" -> "", anon broadcast)`
|
||||
whisperMessage5 = `test message 5 ("" -> K1, encrypted anon broadcast)`
|
||||
whisperMessage6 = `test message 6 (K2 -> K1, signed+encrypted, to us)`
|
||||
chatID = "testChat"
|
||||
statusJSFilePath = "testdata/status.js"
|
||||
txSendFolder = "testdata/tx-send/"
|
||||
)
|
||||
|
||||
var testConfig *geth.TestConfig
|
||||
|
@ -50,17 +54,17 @@ func TestJailUnInited(t *testing.T) {
|
|||
expectedError := errorWrapper(jail.ErrInvalidJail)
|
||||
|
||||
var jailInstance *jail.Jail
|
||||
response := jailInstance.Parse(CHAT_ID_CALL, ``)
|
||||
response := jailInstance.Parse(chatID, ``)
|
||||
if response != expectedError {
|
||||
t.Errorf("error expected, but got: %v", response)
|
||||
}
|
||||
|
||||
response = jailInstance.Call(CHAT_ID_CALL, `["commands", "testCommand"]`, `{"val": 12}`)
|
||||
response = jailInstance.Call(chatID, `["commands", "testCommand"]`, `{"val": 12}`)
|
||||
if response != expectedError {
|
||||
t.Errorf("error expected, but got: %v", response)
|
||||
}
|
||||
|
||||
_, err := jailInstance.GetVM(CHAT_ID_CALL)
|
||||
_, err := jailInstance.GetVM(chatID)
|
||||
if err != jail.ErrInvalidJail {
|
||||
t.Errorf("error expected, but got: %v", err)
|
||||
}
|
||||
|
@ -76,18 +80,18 @@ func TestJailUnInited(t *testing.T) {
|
|||
t.Error("jail instance shouldn't be nil at this point")
|
||||
return
|
||||
}
|
||||
statusJS := geth.LoadFromFile(TESTDATA_STATUS_JS) + `;
|
||||
statusJS := geth.LoadFromFile(statusJSFilePath) + `;
|
||||
_status_catalog.commands["testCommand"] = function (params) {
|
||||
return params.val * params.val;
|
||||
};`
|
||||
response = jailInstance.Parse(CHAT_ID_CALL, statusJS)
|
||||
response = jailInstance.Parse(chatID, statusJS)
|
||||
expectedResponse := `{"result": {"commands":{},"responses":{}}}`
|
||||
if response != expectedResponse {
|
||||
t.Errorf("unexpected response received: %v", response)
|
||||
}
|
||||
|
||||
// however, we still expect issue voiced if somebody tries to execute code with Call
|
||||
response = jailInstance.Call(CHAT_ID_CALL, `["commands", "testCommand"]`, `{"val": 12}`)
|
||||
response = jailInstance.Call(chatID, `["commands", "testCommand"]`, `{"val": 12}`)
|
||||
if response != errorWrapper(geth.ErrInvalidGethNode) {
|
||||
t.Errorf("error expected, but got: %v", response)
|
||||
}
|
||||
|
@ -98,7 +102,7 @@ func TestJailUnInited(t *testing.T) {
|
|||
t.Error(err)
|
||||
return
|
||||
}
|
||||
response = jailInstance.Call(CHAT_ID_CALL, `["commands", "testCommand"]`, `{"val": 12}`)
|
||||
response = jailInstance.Call(chatID, `["commands", "testCommand"]`, `{"val": 12}`)
|
||||
expectedResponse = `{"result": 144}`
|
||||
if response != expectedResponse {
|
||||
t.Errorf("expected response is not returned: expected %s, got %s", expectedResponse, response)
|
||||
|
@ -125,7 +129,7 @@ func TestJailInit(t *testing.T) {
|
|||
return x * x;
|
||||
};
|
||||
`
|
||||
response := jailInstance.Parse(CHAT_ID_INIT, extraCode)
|
||||
response := jailInstance.Parse("newChat", extraCode)
|
||||
|
||||
expectedResponse := `{"result": {"foo":"bar"}}`
|
||||
|
||||
|
@ -145,22 +149,22 @@ func TestJailFunctionCall(t *testing.T) {
|
|||
jailInstance := jail.Init("")
|
||||
|
||||
// load Status JS and add test command to it
|
||||
statusJS := geth.LoadFromFile(TESTDATA_STATUS_JS) + `;
|
||||
statusJS := geth.LoadFromFile(statusJSFilePath) + `;
|
||||
_status_catalog.commands["testCommand"] = function (params) {
|
||||
return params.val * params.val;
|
||||
};`
|
||||
jailInstance.Parse(CHAT_ID_CALL, statusJS)
|
||||
jailInstance.Parse(chatID, statusJS)
|
||||
|
||||
// call with wrong chat id
|
||||
response := jailInstance.Call(CHAT_ID_NON_EXISTENT, "", "")
|
||||
expectedError := `{"error":"Cell[CHAT_IDNON_EXISTENT] doesn't exist."}`
|
||||
response := jailInstance.Call("chatIdNonExistent", "", "")
|
||||
expectedError := `{"error":"Cell[chatIdNonExistent] doesn't exist."}`
|
||||
if response != expectedError {
|
||||
t.Errorf("expected error is not returned: expected %s, got %s", expectedError, response)
|
||||
return
|
||||
}
|
||||
|
||||
// call extraFunc()
|
||||
response = jailInstance.Call(CHAT_ID_CALL, `["commands", "testCommand"]`, `{"val": 12}`)
|
||||
response = jailInstance.Call(chatID, `["commands", "testCommand"]`, `{"val": 12}`)
|
||||
expectedResponse := `{"result": 144}`
|
||||
if response != expectedResponse {
|
||||
t.Errorf("expected response is not returned: expected %s, got %s", expectedResponse, response)
|
||||
|
@ -178,11 +182,11 @@ func TestJailRPCSend(t *testing.T) {
|
|||
jailInstance := jail.Init("")
|
||||
|
||||
// load Status JS and add test command to it
|
||||
statusJS := geth.LoadFromFile(TESTDATA_STATUS_JS)
|
||||
jailInstance.Parse(CHAT_ID_CALL, statusJS)
|
||||
statusJS := geth.LoadFromFile(statusJSFilePath)
|
||||
jailInstance.Parse(chatID, statusJS)
|
||||
|
||||
// obtain VM for a given chat (to send custom JS to jailed version of Send())
|
||||
vm, err := jailInstance.GetVM(CHAT_ID_CALL)
|
||||
vm, err := jailInstance.GetVM(chatID)
|
||||
if err != nil {
|
||||
t.Errorf("cannot get VM: %v", err)
|
||||
return
|
||||
|
@ -371,16 +375,16 @@ func TestJailSendQueuedTransaction(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, test := range tests {
|
||||
jailInstance := jail.Init(geth.LoadFromFile(TESTDATA_TX_SEND_JS + test.file))
|
||||
jailInstance := jail.Init(geth.LoadFromFile(txSendFolder + test.file))
|
||||
geth.PanicAfter(60*time.Second, txCompletedSuccessfully, test.name)
|
||||
jailInstance.Parse(CHAT_ID_SEND, ``)
|
||||
jailInstance.Parse(chatID, ``)
|
||||
|
||||
requireMessageId = test.requireMessageId
|
||||
|
||||
for _, command := range test.commands {
|
||||
go func(jail *jail.Jail, test testCase, command testCommand) {
|
||||
t.Logf("->%s: %s", test.name, command.command)
|
||||
response := jail.Call(CHAT_ID_SEND, command.command, command.params)
|
||||
response := jail.Call(chatID, command.command, command.params)
|
||||
var txHash common.Hash
|
||||
if command.command == `["commands", "send"]` {
|
||||
txHash = <-txHashes
|
||||
|
@ -428,16 +432,16 @@ func TestJailGetVM(t *testing.T) {
|
|||
|
||||
jailInstance := jail.Init("")
|
||||
|
||||
expectedError := `Cell[` + CHAT_ID_NON_EXISTENT + `] doesn't exist.`
|
||||
_, err = jailInstance.GetVM(CHAT_ID_NON_EXISTENT)
|
||||
expectedError := `Cell[nonExistentChat] doesn't exist.`
|
||||
_, err = jailInstance.GetVM("nonExistentChat")
|
||||
if err == nil || err.Error() != expectedError {
|
||||
t.Error("expected error, but call succeeded")
|
||||
}
|
||||
|
||||
// now let's create VM..
|
||||
jailInstance.Parse(CHAT_ID_CALL, ``)
|
||||
jailInstance.Parse(chatID, ``)
|
||||
// ..and see if VM becomes available
|
||||
_, err = jailInstance.GetVM(CHAT_ID_CALL)
|
||||
_, err = jailInstance.GetVM(chatID)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -451,10 +455,10 @@ func TestIsConnected(t *testing.T) {
|
|||
}
|
||||
|
||||
jailInstance := jail.Init("")
|
||||
jailInstance.Parse(CHAT_ID_CALL, "")
|
||||
jailInstance.Parse(chatID, "")
|
||||
|
||||
// obtain VM for a given chat (to send custom JS to jailed version of Send())
|
||||
vm, err := jailInstance.GetVM(CHAT_ID_CALL)
|
||||
vm, err := jailInstance.GetVM(chatID)
|
||||
if err != nil {
|
||||
t.Errorf("cannot get VM: %v", err)
|
||||
return
|
||||
|
@ -496,10 +500,10 @@ func TestLocalStorageSet(t *testing.T) {
|
|||
}
|
||||
|
||||
jailInstance := jail.Init("")
|
||||
jailInstance.Parse(CHAT_ID_CALL, "")
|
||||
jailInstance.Parse(chatID, "")
|
||||
|
||||
// obtain VM for a given chat (to send custom JS to jailed version of Send())
|
||||
vm, err := jailInstance.GetVM(CHAT_ID_CALL)
|
||||
vm, err := jailInstance.GetVM(chatID)
|
||||
if err != nil {
|
||||
t.Errorf("cannot get VM: %v", err)
|
||||
return
|
||||
|
@ -523,8 +527,8 @@ func TestLocalStorageSet(t *testing.T) {
|
|||
t.Error("Chat id is required, but not found")
|
||||
return
|
||||
}
|
||||
if chatId != CHAT_ID_CALL {
|
||||
t.Errorf("incorrect chat id: expected %q, got: %q", CHAT_ID_CALL, chatId)
|
||||
if chatId != chatID {
|
||||
t.Errorf("incorrect chat id: expected %q, got: %q", chatID, chatId)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -588,10 +592,10 @@ func TestContractDeployment(t *testing.T) {
|
|||
}
|
||||
|
||||
jailInstance := jail.Init("")
|
||||
jailInstance.Parse(CHAT_ID_CALL, "")
|
||||
jailInstance.Parse(chatID, "")
|
||||
|
||||
// obtain VM for a given chat (to send custom JS to jailed version of Send())
|
||||
vm, err := jailInstance.GetVM(CHAT_ID_CALL)
|
||||
vm, err := jailInstance.GetVM(chatID)
|
||||
if err != nil {
|
||||
t.Errorf("cannot get VM: %v", err)
|
||||
return
|
||||
|
@ -678,10 +682,10 @@ func TestGasEstimation(t *testing.T) {
|
|||
}
|
||||
|
||||
jailInstance := jail.Init("")
|
||||
jailInstance.Parse(CHAT_ID_CALL, "")
|
||||
jailInstance.Parse(chatID, "")
|
||||
|
||||
// obtain VM for a given chat (to send custom JS to jailed version of Send())
|
||||
vm, err := jailInstance.GetVM(CHAT_ID_CALL)
|
||||
vm, err := jailInstance.GetVM(chatID)
|
||||
if err != nil {
|
||||
t.Errorf("cannot get VM: %v", err)
|
||||
return
|
||||
|
@ -758,3 +762,381 @@ func TestGasEstimation(t *testing.T) {
|
|||
return
|
||||
}
|
||||
}
|
||||
|
||||
func TestJailWhisper(t *testing.T) {
|
||||
err := geth.PrepareTestNode()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
whisperService, err := geth.NodeManagerInstance().WhisperService()
|
||||
if err != nil {
|
||||
t.Errorf("whisper service not running: %v", err)
|
||||
}
|
||||
whisperAPI := whisper.NewPublicWhisperAPI(whisperService)
|
||||
|
||||
// account1
|
||||
_, accountKey1, err := geth.AddressToDecryptedAccount(testConfig.Account1.Address, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
accountKey1Hex := common.ToHex(crypto.FromECDSAPub(&accountKey1.PrivateKey.PublicKey))
|
||||
|
||||
whisperService.AddIdentity(accountKey1.PrivateKey)
|
||||
if ok, err := whisperAPI.HasIdentity(accountKey1Hex); err != nil || !ok {
|
||||
t.Fatalf("identity not injected: %v", accountKey1Hex)
|
||||
}
|
||||
|
||||
// account2
|
||||
_, accountKey2, err := geth.AddressToDecryptedAccount(testConfig.Account2.Address, testConfig.Account2.Password)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
accountKey2Hex := common.ToHex(crypto.FromECDSAPub(&accountKey2.PrivateKey.PublicKey))
|
||||
|
||||
whisperService.AddIdentity(accountKey2.PrivateKey)
|
||||
if ok, err := whisperAPI.HasIdentity(accountKey2Hex); err != nil || !ok {
|
||||
t.Fatalf("identity not injected: %v", accountKey2Hex)
|
||||
}
|
||||
|
||||
passedTests := map[string]bool{
|
||||
whisperMessage1: false,
|
||||
whisperMessage2: false,
|
||||
whisperMessage3: false,
|
||||
whisperMessage4: false,
|
||||
whisperMessage5: false,
|
||||
whisperMessage6: false,
|
||||
}
|
||||
installedFilters := map[string]string{
|
||||
whisperMessage1: "",
|
||||
whisperMessage2: "",
|
||||
whisperMessage3: "",
|
||||
whisperMessage4: "",
|
||||
whisperMessage5: "",
|
||||
whisperMessage6: "",
|
||||
}
|
||||
|
||||
jailInstance := jail.Init("")
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
testCode string
|
||||
useFilter bool
|
||||
}{
|
||||
{
|
||||
"test 0: ensure correct version of Whisper is used",
|
||||
`
|
||||
var expectedVersion = '0x5';
|
||||
if (web3.version.whisper != expectedVersion) {
|
||||
throw 'unexpected shh version, expected: ' + expectedVersion + ', got: ' + web3.version.whisper;
|
||||
}
|
||||
`,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"test 1: encrypted signed message from us (From != nil && To != nil)",
|
||||
`
|
||||
var identity1 = '` + accountKey1Hex + `';
|
||||
if (!web3.shh.hasIdentity(identity1)) {
|
||||
throw 'idenitity "` + accountKey1Hex + `" not found in whisper';
|
||||
}
|
||||
|
||||
var identity2 = '` + accountKey2Hex + `';
|
||||
if (!web3.shh.hasIdentity(identity2)) {
|
||||
throw 'idenitity "` + accountKey2Hex + `" not found in whisper';
|
||||
}
|
||||
|
||||
var topic = 'example1';
|
||||
var payload = '` + whisperMessage1 + `';
|
||||
|
||||
// start watching for messages
|
||||
var filter = shh.filter({
|
||||
from: identity1,
|
||||
to: identity2,
|
||||
topics: [web3.fromAscii(topic)]
|
||||
});
|
||||
|
||||
// post message
|
||||
var message = {
|
||||
from: identity1,
|
||||
to: identity2,
|
||||
topics: [web3.fromAscii(topic)],
|
||||
payload: payload,
|
||||
ttl: 20,
|
||||
};
|
||||
var err = shh.post(message)
|
||||
if (err !== null) {
|
||||
throw 'message not sent: ' + message;
|
||||
}
|
||||
|
||||
var filterName = '` + whisperMessage1 + `';
|
||||
var filterId = filter.filterId;
|
||||
if (!filterId) {
|
||||
throw 'filter not installed properly';
|
||||
}
|
||||
`,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"test 2: encrypted signed message to yourself (From != nil && To != nil)",
|
||||
`
|
||||
var identity = '` + accountKey1Hex + `';
|
||||
if (!web3.shh.hasIdentity(identity)) {
|
||||
throw 'idenitity "` + accountKey1Hex + `" not found in whisper';
|
||||
}
|
||||
|
||||
var topic = 'example2';
|
||||
var payload = '` + whisperMessage2 + `';
|
||||
|
||||
// start watching for messages
|
||||
var filter = shh.filter({
|
||||
from: identity,
|
||||
to: identity,
|
||||
topics: [web3.fromAscii(topic)],
|
||||
});
|
||||
|
||||
// post message
|
||||
var message = {
|
||||
from: identity,
|
||||
to: identity,
|
||||
topics: [web3.fromAscii(topic)],
|
||||
payload: payload,
|
||||
ttl: 20,
|
||||
};
|
||||
var err = shh.post(message)
|
||||
if (err !== null) {
|
||||
throw 'message not sent: ' + message;
|
||||
}
|
||||
|
||||
var filterName = '` + whisperMessage2 + `';
|
||||
var filterId = filter.filterId;
|
||||
if (!filterId) {
|
||||
throw 'filter not installed properly';
|
||||
}
|
||||
`,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"test 3: signed (known sender) broadcast (From != nil && To == nil)",
|
||||
`
|
||||
var identity = '` + accountKey1Hex + `';
|
||||
if (!web3.shh.hasIdentity(identity)) {
|
||||
throw 'idenitity "` + accountKey1Hex + `" not found in whisper';
|
||||
}
|
||||
|
||||
var topic = 'example3';
|
||||
var payload = '` + whisperMessage3 + `';
|
||||
|
||||
// generate symmetric key (if doesn't already exist)
|
||||
if (!shh.hasSymKey(topic)) {
|
||||
shh.addSymKey(topic, "0xdeadbeef"); // alternatively: shh.generateSymKey("example3");
|
||||
// to delete key, rely on: shh.deleteSymKey(topic);
|
||||
}
|
||||
|
||||
// start watching for messages
|
||||
var filter = shh.filter({
|
||||
from: identity,
|
||||
topics: [web3.fromAscii(topic)],
|
||||
keyname: topic // you can use some other name for key too
|
||||
});
|
||||
|
||||
// post message
|
||||
var message = {
|
||||
from: identity,
|
||||
topics: [web3.fromAscii(topic)],
|
||||
payload: payload,
|
||||
ttl: 20,
|
||||
keyname: topic
|
||||
};
|
||||
var err = shh.post(message)
|
||||
if (err !== null) {
|
||||
throw 'message not sent: ' + message;
|
||||
}
|
||||
|
||||
var filterName = '` + whisperMessage3 + `';
|
||||
var filterId = filter.filterId;
|
||||
if (!filterId) {
|
||||
throw 'filter not installed properly';
|
||||
}
|
||||
`,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"test 4: anonymous broadcast (From == nil && To == nil)",
|
||||
`
|
||||
var topic = 'example4';
|
||||
var payload = '` + whisperMessage4 + `';
|
||||
|
||||
// generate symmetric key (if doesn't already exist)
|
||||
if (!shh.hasSymKey(topic)) {
|
||||
shh.addSymKey(topic, "0xdeadbeef"); // alternatively: shh.generateSymKey("example3");
|
||||
// to delete key, rely on: shh.deleteSymKey(topic);
|
||||
}
|
||||
|
||||
// start watching for messages
|
||||
var filter = shh.filter({
|
||||
topics: [web3.fromAscii(topic)],
|
||||
keyname: topic // you can use some other name for key too
|
||||
});
|
||||
|
||||
// post message
|
||||
var message = {
|
||||
topics: [web3.fromAscii(topic)],
|
||||
payload: payload,
|
||||
ttl: 20,
|
||||
keyname: topic
|
||||
};
|
||||
var err = shh.post(message)
|
||||
if (err !== null) {
|
||||
throw 'message not sent: ' + err;
|
||||
}
|
||||
|
||||
var filterName = '` + whisperMessage4 + `';
|
||||
var filterId = filter.filterId;
|
||||
if (!filterId) {
|
||||
throw 'filter not installed properly';
|
||||
}
|
||||
`,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"test 5: encrypted anonymous message (From == nil && To != nil)",
|
||||
`
|
||||
var identity = '` + accountKey2Hex + `';
|
||||
if (!web3.shh.hasIdentity(identity)) {
|
||||
throw 'idenitity "` + accountKey2Hex + `" not found in whisper';
|
||||
}
|
||||
|
||||
var topic = 'example5';
|
||||
var payload = '` + whisperMessage5 + `';
|
||||
|
||||
// start watching for messages
|
||||
var filter = shh.filter({
|
||||
to: identity,
|
||||
topics: [web3.fromAscii(topic)],
|
||||
});
|
||||
|
||||
// post message
|
||||
var message = {
|
||||
to: identity,
|
||||
topics: [web3.fromAscii(topic)],
|
||||
payload: payload,
|
||||
ttl: 20
|
||||
};
|
||||
var err = shh.post(message)
|
||||
if (err !== null) {
|
||||
throw 'message not sent: ' + message;
|
||||
}
|
||||
|
||||
var filterName = '` + whisperMessage5 + `';
|
||||
var filterId = filter.filterId;
|
||||
if (!filterId) {
|
||||
throw 'filter not installed properly';
|
||||
}
|
||||
`,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"test 6: encrypted signed response to us (From != nil && To != nil)",
|
||||
`
|
||||
var identity1 = '` + accountKey1Hex + `';
|
||||
if (!web3.shh.hasIdentity(identity1)) {
|
||||
throw 'idenitity "` + accountKey1Hex + `" not found in whisper';
|
||||
}
|
||||
|
||||
var identity2 = '` + accountKey2Hex + `';
|
||||
if (!web3.shh.hasIdentity(identity2)) {
|
||||
throw 'idenitity "` + accountKey2Hex + `" not found in whisper';
|
||||
}
|
||||
|
||||
var topic = 'example6';
|
||||
var payload = '` + whisperMessage6 + `';
|
||||
|
||||
// start watching for messages
|
||||
var filter = shh.filter({
|
||||
from: identity2,
|
||||
to: identity1,
|
||||
topics: [web3.fromAscii(topic)]
|
||||
});
|
||||
|
||||
// post message
|
||||
var message = {
|
||||
from: identity2,
|
||||
to: identity1,
|
||||
topics: [web3.fromAscii(topic)],
|
||||
payload: payload,
|
||||
ttl: 20
|
||||
};
|
||||
var err = shh.post(message)
|
||||
if (err !== null) {
|
||||
throw 'message not sent: ' + message;
|
||||
}
|
||||
|
||||
var filterName = '` + whisperMessage6 + `';
|
||||
var filterId = filter.filterId;
|
||||
if (!filterId) {
|
||||
throw 'filter not installed properly';
|
||||
}
|
||||
`,
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Log(testCase.name)
|
||||
testCaseKey := crypto.Keccak256Hash([]byte(testCase.name)).Hex()
|
||||
jailInstance.Parse(testCaseKey, `var shh = web3.shh;`)
|
||||
vm, err := jailInstance.GetVM(testCaseKey)
|
||||
if err != nil {
|
||||
t.Errorf("cannot get VM: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// post messages
|
||||
if _, err := vm.Run(testCase.testCode); err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
if !testCase.useFilter {
|
||||
continue
|
||||
}
|
||||
|
||||
// update installed filters
|
||||
filterId, err := vm.Get("filterId")
|
||||
if err != nil {
|
||||
t.Errorf("cannot get filterId: %v", err)
|
||||
return
|
||||
}
|
||||
filterName, err := vm.Get("filterName")
|
||||
if err != nil {
|
||||
t.Errorf("cannot get filterName: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := installedFilters[filterName.String()]; !ok {
|
||||
t.Fatal("unrecognized filter")
|
||||
}
|
||||
|
||||
installedFilters[filterName.String()] = filterId.String()
|
||||
}
|
||||
|
||||
time.Sleep(2 * time.Second) // allow whisper to poll
|
||||
|
||||
for testKey, filter := range installedFilters {
|
||||
if filter != "" {
|
||||
t.Logf("filter found: %v", filter)
|
||||
for _, message := range whisperAPI.GetFilterChanges(filter) {
|
||||
t.Logf("message found: %s", common.FromHex(message.Payload))
|
||||
passedTests[testKey] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for testName, passedTest := range passedTests {
|
||||
if !passedTest {
|
||||
t.Fatalf("test not passed: %v", testName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,87 @@
|
|||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>web3.js sample</title>
|
||||
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.1.1.js"
|
||||
integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA="
|
||||
crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="./bignumber.js"></script>
|
||||
<script type="text/javascript" src="./web3.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
var web3 = new Web3();
|
||||
var shh = web3.shh;
|
||||
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8645'));
|
||||
|
||||
var identity = '0x04eedbaafd6adf4a9233a13e7b1c3c14461fffeba2e9054b8d456ce5f6ebeafadcbf3dce3716253fbc391277fa5a086b60b283daf61fb5b1f26895f456c2f31ae3';
|
||||
if (!web3.shh.hasIdentity(identity)) {
|
||||
throw 'idenitity "0x04eedbaafd6adf4a9233a13e7b1c3c14461fffeba2e9054b8d456ce5f6ebeafadcbf3dce3716253fbc391277fa5a086b60b283daf61fb5b1f26895f456c2f31ae3" not found in whisper';
|
||||
}
|
||||
|
||||
var topic = 'example3';
|
||||
var payload = 'test message 3 (K1 -> "", signed broadcast)';
|
||||
|
||||
// generate symmetric key (if doesn't already exist)
|
||||
if (!shh.hasSymKey(topic)) {
|
||||
shh.addSymKey(topic, "0xdeadbeef"); // alternatively: shh.generateSymKey("example3");
|
||||
// to delete key, rely on: shh.deleteSymKey(topic);
|
||||
}
|
||||
|
||||
// start watching for messages
|
||||
var filter = shh.filter({
|
||||
from: identity,
|
||||
topics: [web3.fromAscii(topic)],
|
||||
keyname: topic // you can use some other name for key too
|
||||
});
|
||||
filter.watch(function(error, result){
|
||||
if (!error) {
|
||||
console.log("Message received1: ", result);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
setTimeout(function () {
|
||||
var message = {
|
||||
from: identity,
|
||||
topics: [web3.fromAscii(topic)],
|
||||
payload: payload,
|
||||
ttl: 20,
|
||||
keyname: topic
|
||||
};
|
||||
var err = shh.post(message)
|
||||
if (err !== null) {
|
||||
console.log("message NOT sent")
|
||||
} else {
|
||||
console.log("message sent OK")
|
||||
}
|
||||
}, 3000)
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Static navbar -->
|
||||
<nav class="navbar navbar-default navbar-static-top">
|
||||
<div class="container">
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<div class="jumbotron">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
|
@ -3453,6 +3453,7 @@ var getOptions = function (options) {
|
|||
topics: options.topics,
|
||||
from: options.from,
|
||||
to: options.to,
|
||||
keyname: options.keyname,
|
||||
address: options.address,
|
||||
fromBlock: formatters.inputBlockNumberFormatter(options.fromBlock),
|
||||
toBlock: formatters.inputBlockNumberFormatter(options.toBlock)
|
||||
|
@ -5646,12 +5647,40 @@ var methods = function () {
|
|||
params: 0
|
||||
});
|
||||
|
||||
var generateSymKey = new Method({
|
||||
name: 'generateSymKey',
|
||||
call: 'shh_generateSymKey',
|
||||
params: 1
|
||||
});
|
||||
|
||||
var hasSymKey = new Method({
|
||||
name: 'hasSymKey',
|
||||
call: 'shh_hasSymKey',
|
||||
params: 1
|
||||
});
|
||||
|
||||
var deleteSymKey = new Method({
|
||||
name: 'deleteSymKey',
|
||||
call: 'shh_deleteSymKey',
|
||||
params: 1
|
||||
});
|
||||
|
||||
var addSymKey = new Method({
|
||||
name: 'addSymKey',
|
||||
call: 'shh_addSymKey',
|
||||
params: 2
|
||||
});
|
||||
|
||||
return [
|
||||
post,
|
||||
newIdentity,
|
||||
hasIdentity,
|
||||
newGroup,
|
||||
addToGroup
|
||||
addToGroup,
|
||||
generateSymKey,
|
||||
hasSymKey,
|
||||
deleteSymKey,
|
||||
addSymKey
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||
gethparams "github.com/ethereum/go-ethereum/params"
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv2"
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv2"
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,34 +5,44 @@ var MainnetBootnodes = []string{}
|
|||
|
||||
// TestnetBootnodes are the enode URLs of the P2P bootstrap nodes running on the Ropsten test network.
|
||||
var TestnetBootnodes = []string{
|
||||
"enode://bc4a130219ae94c2a66e3ec3377c2a460e006d56b877d5e8edb0d0f8064cf400f117a53a5389f552c9e1a122b9a07eeaa41e7ed885268ee825b6a788188fb52e@51.15.55.219:30399",
|
||||
"enode://bc4a130219ae94c2a66e3ec3377c2a460e006d56b877d5e8edb0d0f8064cf400f117a53a5389f552c9e1a122b9a07eeaa41e7ed885268ee825b6a788188fb52e@51.15.55.219:30379",
|
||||
//"enode://bc4a130219ae94c2a66e3ec3377c2a460e006d56b877d5e8edb0d0f8064cf400f117a53a5389f552c9e1a122b9a07eeaa41e7ed885268ee825b6a788188fb52e@51.15.55.219:30399",
|
||||
"enode://fbddff478e18292dc32b90f139bf773a08da89ffe29208e4de0091f6c589e60fccfaf16d4f4a76be49f57782c061ec8ea97078601c6f367feabda740f5ce8246@51.15.55.219:30303",
|
||||
|
||||
"enode://df20352d07924ffe93e67ee7e81105d7b250f7932ff4e0351da2cfa17282e53f765895c32cda36b70dfb98def0b472b29d79321737035641bf3bcf595dcc1041@51.15.35.110:30399",
|
||||
"enode://df20352d07924ffe93e67ee7e81105d7b250f7932ff4e0351da2cfa17282e53f765895c32cda36b70dfb98def0b472b29d79321737035641bf3bcf595dcc1041@51.15.35.110:30379",
|
||||
//"enode://df20352d07924ffe93e67ee7e81105d7b250f7932ff4e0351da2cfa17282e53f765895c32cda36b70dfb98def0b472b29d79321737035641bf3bcf595dcc1041@51.15.35.110:30399",
|
||||
"enode://4e5ee0487a4d8349ab9a9925b00eed0f976d98972c5a22f43fd50d1424897757032c36f273b434a4d3e013a2544eca74a9d1a0419f9f07f7bb43182a73df3690@51.15.35.110:30303",
|
||||
|
||||
"enode://2cbcc7b3d067581072066143e0fade0d007e80ecc8f86eb475200c3da3a6d81dd4e1e7051fc3dfaee337f110ceec61594a901b09e36eb367629ddff6e1dfd955@51.15.34.3:30399",
|
||||
"enode://2cbcc7b3d067581072066143e0fade0d007e80ecc8f86eb475200c3da3a6d81dd4e1e7051fc3dfaee337f110ceec61594a901b09e36eb367629ddff6e1dfd955@51.15.34.3:30379",
|
||||
//"enode://2cbcc7b3d067581072066143e0fade0d007e80ecc8f86eb475200c3da3a6d81dd4e1e7051fc3dfaee337f110ceec61594a901b09e36eb367629ddff6e1dfd955@51.15.34.3:30399",
|
||||
"enode://18efd9afb60443e00fed602cc0df526cd1d8543d2f6037df9380eb973d30b5fd04ac9f221053f82034581051bfd6e54356a99af2255f1a674d71d17440a6c95b@51.15.34.3:30303",
|
||||
|
||||
"enode://cdb95f3d866472a74195342979ffea4ed7f9b68cd1e8c6f9a25b3197c221f01bc076ccba760341d8b69bb6bfbc9bf4fdeabd0caa99ee0bf4e79917fa1f42423c@51.15.56.154:30399",
|
||||
"enode://cdb95f3d866472a74195342979ffea4ed7f9b68cd1e8c6f9a25b3197c221f01bc076ccba760341d8b69bb6bfbc9bf4fdeabd0caa99ee0bf4e79917fa1f42423c@51.15.56.154:30379",
|
||||
//"enode://cdb95f3d866472a74195342979ffea4ed7f9b68cd1e8c6f9a25b3197c221f01bc076ccba760341d8b69bb6bfbc9bf4fdeabd0caa99ee0bf4e79917fa1f42423c@51.15.56.154:30399",
|
||||
"enode://5b99c0cb372299fd3f2d94612a682990722eb7c3a252dacefc8270eb7f172fc699c1ddfad826fbfc979270538e8d89bd6919703eb9ef526eac0a45e9fb455123@51.15.56.154:30303",
|
||||
|
||||
"enode://5ce8e96d9589671767a7b1c6b9a34bcf532587387eb062de712a9f716a66f05f412126121ce4d97330bc5dc7a4938ff1ecc22306b0b8b97a7f748c6f5f59c620@51.15.60.23:30399",
|
||||
"enode://5ce8e96d9589671767a7b1c6b9a34bcf532587387eb062de712a9f716a66f05f412126121ce4d97330bc5dc7a4938ff1ecc22306b0b8b97a7f748c6f5f59c620@51.15.60.23:30379",
|
||||
//"enode://5ce8e96d9589671767a7b1c6b9a34bcf532587387eb062de712a9f716a66f05f412126121ce4d97330bc5dc7a4938ff1ecc22306b0b8b97a7f748c6f5f59c620@51.15.60.23:30399",
|
||||
"enode://0e1d4d0fcfe888bf8a478b0fd89760a47733a5c04cd47de353295a6eb8dde8f54821b31196527d0c5c73a7024dc9ff34127692d237840fc09c312b3a19cd28fe@51.15.60.23:30303",
|
||||
|
||||
"enode://6853f434735e540f0fcd85ffebcaa75280d1171ca9a205e8c41d87428d71b07ad14ab266236b64268467ccc462679edc888f76326418d18d7bcfe8d1159391aa@51.15.61.194:30399",
|
||||
"enode://6853f434735e540f0fcd85ffebcaa75280d1171ca9a205e8c41d87428d71b07ad14ab266236b64268467ccc462679edc888f76326418d18d7bcfe8d1159391aa@51.15.61.194:30379",
|
||||
//"enode://6853f434735e540f0fcd85ffebcaa75280d1171ca9a205e8c41d87428d71b07ad14ab266236b64268467ccc462679edc888f76326418d18d7bcfe8d1159391aa@51.15.61.194:30399",
|
||||
"enode://1fa2dfe6b925ca753496ea197c973b66ef889ef4de2bf52acd5b8665c0cc2e8b95fbd192e764f10735f589297f1ae533f350f004e403063e8d4ad979aae44c12@51.15.61.194:30303",
|
||||
|
||||
"enode://a8f1dae49f665c566734e002f89c1feb9b01e3ed09bdea6199aa6093f25085c4777fd553d2d1d14457286c24aaa48eaf6db99315e0caf62d97ea8bce801ae7c1@51.15.35.2:30399",
|
||||
"enode://a8f1dae49f665c566734e002f89c1feb9b01e3ed09bdea6199aa6093f25085c4777fd553d2d1d14457286c24aaa48eaf6db99315e0caf62d97ea8bce801ae7c1@51.15.35.2:30379",
|
||||
//"enode://a8f1dae49f665c566734e002f89c1feb9b01e3ed09bdea6199aa6093f25085c4777fd553d2d1d14457286c24aaa48eaf6db99315e0caf62d97ea8bce801ae7c1@51.15.35.2:30399",
|
||||
"enode://44b91c043bcd96bc5279524f1bfe32df0670374135435ebacb29ba5d0e18192623e63ead711c9c363afdf2500fac423116ac28bdd2d700bd70e096326f95c63f@51.15.35.2:30303",
|
||||
|
||||
"enode://64278f1e4224a5ff4608da54b7b045ae0b875a332c57e6f9b4cbb3e9ac1e56a1d5b91ff2def2662c767146b3f7f08924c15f66d41352a18ebe71832c35f6a0cf@51.15.54.229:30399",
|
||||
"enode://64278f1e4224a5ff4608da54b7b045ae0b875a332c57e6f9b4cbb3e9ac1e56a1d5b91ff2def2662c767146b3f7f08924c15f66d41352a18ebe71832c35f6a0cf@51.15.54.229:30379",
|
||||
//"enode://64278f1e4224a5ff4608da54b7b045ae0b875a332c57e6f9b4cbb3e9ac1e56a1d5b91ff2def2662c767146b3f7f08924c15f66d41352a18ebe71832c35f6a0cf@51.15.54.229:30399",
|
||||
"enode://fb7622d3a50dc603f5c76919dd99c4112e5925cb891a67086b9dce581166fbdad361fd0bfb7ff128ab8f5e24e209e0b923668fbddb7e8b99edb82c1e3d782a80@51.15.54.229:30303",
|
||||
|
||||
"enode://e1fcf9e7a47ab43a546d1c1633c511d98d13646bbf5c82d74ff98a1c88e54567b0be6574e977164e1b4c997ef8e79b19f1e12e85a6230c746dd74206fe37cfa0@51.15.35.70:30399",
|
||||
"enode://e1fcf9e7a47ab43a546d1c1633c511d98d13646bbf5c82d74ff98a1c88e54567b0be6574e977164e1b4c997ef8e79b19f1e12e85a6230c746dd74206fe37cfa0@51.15.35.70:30379",
|
||||
//"enode://e1fcf9e7a47ab43a546d1c1633c511d98d13646bbf5c82d74ff98a1c88e54567b0be6574e977164e1b4c997ef8e79b19f1e12e85a6230c746dd74206fe37cfa0@51.15.35.70:30399",
|
||||
"enode://14c2960f57f6d63ed541cf64226aafbc7a21c40c6e4935a2e58fd2466fa7d06ec32082734c64d32f7c4692f4b90f26d019f472ba55cdda6d624ef4d7d8441285@51.15.35.70:30303",
|
||||
|
||||
"enode://a8512bcaae1245fda71d400291dd22937d89947b6fc31283945557abe1281c5a9325ffc11e363cfed6362e4d2d9b941c5b325270662ba43ac8c424168e6567a6@51.15.39.57:30399",
|
||||
"enode://a8512bcaae1245fda71d400291dd22937d89947b6fc31283945557abe1281c5a9325ffc11e363cfed6362e4d2d9b941c5b325270662ba43ac8c424168e6567a6@51.15.39.57:30379",
|
||||
//"enode://a8512bcaae1245fda71d400291dd22937d89947b6fc31283945557abe1281c5a9325ffc11e363cfed6362e4d2d9b941c5b325270662ba43ac8c424168e6567a6@51.15.39.57:30399",
|
||||
"enode://02cfa2b02b5431bfdc1bad0f575de8ea151029fe9a9c689074793d704d1b428255bd111bf578f0b4fcaa18267da7c335db9557e1012434f4a8ab2c25f4b3da4d@51.15.39.57:30303",
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ func TestQueuedContracts(t *testing.T) {
|
|||
t.Errorf("Test failed: cannot send transaction: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(txHash, txHashCheck) {
|
||||
if txHashCheck.Hex() != txHash.Hex() {
|
||||
t.Errorf("Transaction hash returned from SendTransaction is invalid: expected %s, got %s", txHashCheck.Hex(), txHash.Hex())
|
||||
return
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ func TestQueuedTransactions(t *testing.T) {
|
|||
t.Errorf("Test failed: cannot send transaction: %v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(txHash, txHashCheck) {
|
||||
if txHashCheck.Hex() != txHash.Hex() {
|
||||
t.Errorf("Transaction hash returned from SendTransaction is invalid: expected %s, got %s", txHashCheck.Hex(), txHash.Hex())
|
||||
return
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ func TestDoubleCompleteQueuedTransactions(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(txHash, txHashCheck) {
|
||||
if txHashCheck.Hex() != txHash.Hex() {
|
||||
t.Errorf("tx hash returned from SendTransaction is invalid: expected %s, got %s", txHashCheck.Hex(), txHash.Hex())
|
||||
return
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/logger"
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
|
@ -168,13 +169,23 @@ func PrepareTestNode() (err error) {
|
|||
}
|
||||
|
||||
// import test account (with test ether on it)
|
||||
dst := filepath.Join(TestDataDir, "keystore", "test-account.pk")
|
||||
if _, err := os.Stat(dst); os.IsNotExist(err) {
|
||||
err = CopyFile(dst, filepath.Join(RootDir, "data", "test-account.pk"))
|
||||
if err != nil {
|
||||
glog.V(logger.Warn).Infof("cannot copy test account PK: %v", err)
|
||||
return err
|
||||
importTestAccount := func(accountFile string) error {
|
||||
dst := filepath.Join(TestDataDir, "keystore", accountFile)
|
||||
if _, err := os.Stat(dst); os.IsNotExist(err) {
|
||||
err = CopyFile(dst, filepath.Join(RootDir, "data", accountFile))
|
||||
if err != nil {
|
||||
glog.V(logger.Warn).Infof("cannot copy test account PK: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
if err := importTestAccount("test-account1.pk"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := importTestAccount("test-account2.pk"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// start geth node and wait for it to initialize
|
||||
|
@ -208,8 +219,6 @@ func PrepareTestNode() (err error) {
|
|||
if syncRequired {
|
||||
glog.V(logger.Warn).Infof("Sync is required, it will take %d seconds", testConfig.Node.SyncSeconds)
|
||||
time.Sleep(testConfig.Node.SyncSeconds * time.Second) // LES syncs headers, so that we are up do date when it is done
|
||||
} else {
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -261,3 +270,19 @@ func ParseAccountString(account string) (accounts.Account, error) {
|
|||
|
||||
return accounts.Account{}, ErrInvalidAccountAddressOrKey
|
||||
}
|
||||
|
||||
// AddressToDecryptedAccount tries to load and decrypt account with a given password
|
||||
func AddressToDecryptedAccount(address, password string) (accounts.Account, *keystore.Key, error) {
|
||||
nodeManager := NodeManagerInstance()
|
||||
keyStore, err := nodeManager.AccountKeyStore()
|
||||
if err != nil {
|
||||
return accounts.Account{}, nil, err
|
||||
}
|
||||
|
||||
account, err := ParseAccountString(address)
|
||||
if err != nil {
|
||||
return accounts.Account{}, nil, ErrAddressToAccountMappingFailure
|
||||
}
|
||||
|
||||
return keyStore.AccountDecryptedKey(account, password)
|
||||
}
|
||||
|
|
|
@ -8,10 +8,6 @@ import (
|
|||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv2"
|
||||
)
|
||||
|
||||
var (
|
||||
whisperFilters []int
|
||||
)
|
||||
|
||||
func onWhisperMessage(message *whisper.Message) {
|
||||
SendSignal(SignalEnvelope{
|
||||
Type: "whisper",
|
||||
|
@ -25,36 +21,3 @@ func onWhisperMessage(message *whisper.Message) {
|
|||
},
|
||||
})
|
||||
}
|
||||
|
||||
func AddWhisperFilter(args whisper.NewFilterArgs) int {
|
||||
whisperService, err := NodeManagerInstance().WhisperService()
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
|
||||
filter := whisper.Filter{
|
||||
To: crypto.ToECDSAPub(common.FromHex(args.To)),
|
||||
From: crypto.ToECDSAPub(common.FromHex(args.From)),
|
||||
Topics: whisper.NewFilterTopics(args.Topics...),
|
||||
Fn: onWhisperMessage,
|
||||
}
|
||||
|
||||
id := whisperService.Watch(filter)
|
||||
whisperFilters = append(whisperFilters, id)
|
||||
return id
|
||||
}
|
||||
|
||||
func RemoveWhisperFilter(idFilter int) {
|
||||
whisperService, err := NodeManagerInstance().WhisperService()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
whisperService.Unwatch(idFilter)
|
||||
}
|
||||
|
||||
func ClearWhisperFilters() {
|
||||
for _, idFilter := range whisperFilters {
|
||||
RemoveWhisperFilter(idFilter)
|
||||
}
|
||||
whisperFilters = nil
|
||||
}
|
||||
|
|
|
@ -1,25 +1,15 @@
|
|||
package geth_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv2"
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
|
||||
"github.com/status-im/status-go/geth"
|
||||
)
|
||||
|
||||
const (
|
||||
whisperMessage1 = "test message 1 (K1 -> K1)"
|
||||
whisperMessage2 = "test message 2 (K1 -> '')"
|
||||
whisperMessage3 = "test message 3 ('' -> '')"
|
||||
whisperMessage4 = "test message 4 ('' -> K1)"
|
||||
whisperMessage5 = "test message 5 (K2 -> K1)"
|
||||
)
|
||||
|
||||
func TestWhisperMessaging(t *testing.T) {
|
||||
func TestWhisperFilterRace(t *testing.T) {
|
||||
err := geth.PrepareTestNode()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -33,138 +23,58 @@ func TestWhisperMessaging(t *testing.T) {
|
|||
|
||||
whisperAPI := whisper.NewPublicWhisperAPI(whisperService)
|
||||
|
||||
// prepare message
|
||||
postArgs := whisper.PostArgs{
|
||||
From: "",
|
||||
To: "",
|
||||
TTL: 10,
|
||||
Topics: [][]byte{[]byte("test topic")},
|
||||
Payload: "test message",
|
||||
}
|
||||
|
||||
// create an accounts
|
||||
address1, pubKey1, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
// account1
|
||||
_, accountKey1, err := geth.AddressToDecryptedAccount(testConfig.Account1.Address, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
t.Error("Test failed: could not create account")
|
||||
return
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("Account created: {address: %s, key: %s}", address1, pubKey1)
|
||||
accountKey1Hex := common.ToHex(crypto.FromECDSAPub(&accountKey1.PrivateKey.PublicKey))
|
||||
|
||||
address2, pubKey2, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
whisperService.AddIdentity(accountKey1.PrivateKey)
|
||||
if ok, err := whisperAPI.HasIdentity(accountKey1Hex); err != nil || !ok {
|
||||
t.Fatalf("identity not injected: %v", accountKey1Hex)
|
||||
}
|
||||
|
||||
// account2
|
||||
_, accountKey2, err := geth.AddressToDecryptedAccount(testConfig.Account2.Address, testConfig.Account2.Password)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
t.Error("Test failed: could not create account")
|
||||
return
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("Account created: {address: %s, key: %s}", address2, pubKey2)
|
||||
accountKey2Hex := common.ToHex(crypto.FromECDSAPub(&accountKey2.PrivateKey.PublicKey))
|
||||
|
||||
// start watchers
|
||||
var receivedMessages = map[string]bool{
|
||||
whisperMessage1: false,
|
||||
whisperMessage2: false,
|
||||
whisperMessage3: false,
|
||||
whisperMessage4: false,
|
||||
whisperMessage5: false,
|
||||
}
|
||||
whisperService.Watch(whisper.Filter{
|
||||
//From: crypto.ToECDSAPub(common.FromHex(pubKey1)),
|
||||
//To: crypto.ToECDSAPub(common.FromHex(pubKey2)),
|
||||
Fn: func(msg *whisper.Message) {
|
||||
//t.Logf("Whisper message received: %s", msg.Payload)
|
||||
receivedMessages[string(msg.Payload)] = true
|
||||
},
|
||||
})
|
||||
|
||||
// inject key of newly created account into Whisper, as identity
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
err = geth.SelectAccount(address1, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
}
|
||||
identitySucceess := whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1)))
|
||||
if !identitySucceess || err != nil {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey2))) { // ensure that second id is not injected
|
||||
t.Error("identity already present in whisper")
|
||||
whisperService.AddIdentity(accountKey2.PrivateKey)
|
||||
if ok, err := whisperAPI.HasIdentity(accountKey2Hex); err != nil || !ok {
|
||||
t.Fatalf("identity not injected: %v", accountKey2Hex)
|
||||
}
|
||||
|
||||
// double selecting (shouldn't be a problem)
|
||||
err = geth.SelectAccount(address1, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
}
|
||||
// race filter addition
|
||||
filterAdded := make(chan struct{})
|
||||
allFiltersAdded := make(chan struct{})
|
||||
|
||||
// TEST 0: From != nil && To != nil: encrypted signed message (but we cannot decrypt it - so watchers will not report this)
|
||||
postArgs.From = pubKey1
|
||||
postArgs.To = pubKey2 // owner of that public key will be able to decrypt it
|
||||
postSuccess, err := whisperAPI.Post(postArgs)
|
||||
if !postSuccess || err != nil {
|
||||
t.Errorf("could not post to whisper: %v", err)
|
||||
}
|
||||
|
||||
// TEST 1: From != nil && To != nil: encrypted signed message (to self)
|
||||
postArgs.From = pubKey1
|
||||
postArgs.To = pubKey1
|
||||
postArgs.Payload = whisperMessage1
|
||||
postSuccess, err = whisperAPI.Post(postArgs)
|
||||
if !postSuccess || err != nil {
|
||||
t.Errorf("could not post to whisper: %v", err)
|
||||
}
|
||||
|
||||
// send from account that is not in Whisper identity list
|
||||
postArgs.From = pubKey2
|
||||
postSuccess, err = whisperAPI.Post(postArgs)
|
||||
if err == nil || err.Error() != fmt.Sprintf("unknown identity to send from: %s", pubKey2) {
|
||||
t.Error("expected error not voiced: we are sending from non-injected whisper identity")
|
||||
}
|
||||
|
||||
// TEST 2: From != nil && To == nil: signed broadcast (known sender)
|
||||
postArgs.From = pubKey1
|
||||
postArgs.To = ""
|
||||
postArgs.Payload = whisperMessage2
|
||||
postSuccess, err = whisperAPI.Post(postArgs)
|
||||
if !postSuccess || err != nil {
|
||||
t.Errorf("could not post to whisper: %v", err)
|
||||
}
|
||||
|
||||
// TEST 3: From == nil && To == nil: anonymous broadcast
|
||||
postArgs.From = ""
|
||||
postArgs.To = ""
|
||||
postArgs.Payload = whisperMessage3
|
||||
postSuccess, err = whisperAPI.Post(postArgs)
|
||||
if !postSuccess || err != nil {
|
||||
t.Errorf("could not post to whisper: %v", err)
|
||||
}
|
||||
|
||||
// TEST 4: From == nil && To != nil: encrypted anonymous message
|
||||
postArgs.From = ""
|
||||
postArgs.To = pubKey1
|
||||
postArgs.Payload = whisperMessage4
|
||||
postSuccess, err = whisperAPI.Post(postArgs)
|
||||
if !postSuccess || err != nil {
|
||||
t.Errorf("could not post to whisper: %v", err)
|
||||
}
|
||||
|
||||
// TEST 5: From != nil && To != nil: encrypted and signed response
|
||||
postArgs.From = ""
|
||||
postArgs.To = pubKey1
|
||||
postArgs.Payload = whisperMessage5
|
||||
postSuccess, err = whisperAPI.Post(postArgs)
|
||||
if !postSuccess || err != nil {
|
||||
t.Errorf("could not post to whisper: %v", err)
|
||||
}
|
||||
|
||||
time.Sleep(2 * time.Second) // allow whisper to poll
|
||||
for message, status := range receivedMessages {
|
||||
if !status {
|
||||
t.Errorf("Expected message not received: %s", message)
|
||||
go func() {
|
||||
counter := 10
|
||||
for range filterAdded {
|
||||
counter--
|
||||
if counter <= 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
close(allFiltersAdded)
|
||||
}()
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
go func() {
|
||||
whisperAPI.NewFilter(whisper.WhisperFilterArgs{
|
||||
From: accountKey1Hex,
|
||||
To: accountKey2Hex,
|
||||
Topics: []whisper.TopicType{
|
||||
{0x4e, 0x03, 0x65, 0x7a}, {0x34, 0x60, 0x7c, 0x9b}, {0x21, 0x41, 0x7d, 0xf9},
|
||||
},
|
||||
})
|
||||
filterAdded <- struct{}{}
|
||||
}()
|
||||
}
|
||||
|
||||
<-allFiltersAdded
|
||||
}
|
||||
|
|
|
@ -137,6 +137,13 @@ func (self *Whisper) NewIdentity() *ecdsa.PrivateKey {
|
|||
return key
|
||||
}
|
||||
|
||||
// AddIdentity adds identity into the known identities list (for message decryption).
|
||||
func (self *Whisper) AddIdentity(key *ecdsa.PrivateKey) {
|
||||
self.keysMu.Lock()
|
||||
self.keys[string(crypto.FromECDSAPub(&key.PublicKey))] = key
|
||||
self.keysMu.Unlock()
|
||||
}
|
||||
|
||||
// HasIdentity checks if the the whisper node is configured with the private key
|
||||
// of the specified public pair.
|
||||
func (self *Whisper) HasIdentity(key *ecdsa.PublicKey) bool {
|
||||
|
|
|
@ -377,6 +377,42 @@ type PostArgs struct {
|
|||
PeerID hexutil.Bytes `json:"peerID"`
|
||||
}
|
||||
|
||||
func (args *PostArgs) UnmarshalJSON(data []byte) (err error) {
|
||||
var obj struct {
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
Topics []string `json:"topics"`
|
||||
Payload string `json:"payload"`
|
||||
Priority hexutil.Uint64 `json:"priority"`
|
||||
TTL hexutil.Uint64 `json:"ttl"`
|
||||
KeyName string `json:"keyname"`
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, &obj); err != nil {
|
||||
return err
|
||||
}
|
||||
args.From = obj.From
|
||||
args.To = obj.To
|
||||
args.Payload = []byte(obj.Payload)
|
||||
args.WorkTime = 2
|
||||
args.PoW = MinimumPoW
|
||||
args.TTL = uint32(obj.TTL)
|
||||
args.KeyName = obj.KeyName
|
||||
for j, topic := range obj.Topics {
|
||||
x := common.FromHex(topic)
|
||||
if x == nil {
|
||||
return fmt.Errorf("topic[%d] is invalid", j)
|
||||
}
|
||||
args.Topic = BytesToTopic(x)
|
||||
}
|
||||
|
||||
if objJSON, err := json.Marshal(&obj); err == nil {
|
||||
glog.V(logger.Info).Infoln("shh message posted: ", string(objJSON))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type WhisperFilterArgs struct {
|
||||
To string `json:"to"`
|
||||
From string `json:"from"`
|
||||
|
@ -424,7 +460,7 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
topicsDecoded := make([]TopicType, len(topics))
|
||||
for j, s := range topics {
|
||||
x := common.FromHex(s)
|
||||
if x == nil || len(x) != TopicLength {
|
||||
if x == nil {
|
||||
return fmt.Errorf("topic[%d] is invalid", j)
|
||||
}
|
||||
topicsDecoded[j] = BytesToTopic(x)
|
||||
|
|
|
@ -56,7 +56,7 @@ const (
|
|||
AESNonceMaxLength = 12
|
||||
|
||||
MaxMessageLength = 0x0FFFFF // todo: remove this restriction after testing. this should be regulated by PoW.
|
||||
MinimumPoW = 10.0 // todo: review after testing.
|
||||
MinimumPoW = 0.001 // todo: review after testing.
|
||||
|
||||
padSizeLimitLower = 128 // it can not be less - we don't want to reveal the absence of signature
|
||||
padSizeLimitUpper = 256 // just an arbitrary number, could be changed without losing compatibility
|
||||
|
|
|
@ -21,7 +21,6 @@ package whisperv5
|
|||
import (
|
||||
"crypto/ecdsa"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
@ -116,7 +115,7 @@ func (e *Envelope) Seal(options *MessageParams) error {
|
|||
}
|
||||
|
||||
if target > 0 && bestBit < target {
|
||||
return errors.New("Failed to reach the PoW target, insufficient work time")
|
||||
return fmt.Errorf("Failed to reach the PoW target, insufficient work time. Expected: %v, got: %v", target, bestBit)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -202,6 +202,38 @@ func (w *Whisper) GetIdentity(pubKey string) *ecdsa.PrivateKey {
|
|||
return w.privateKeys[pubKey]
|
||||
}
|
||||
|
||||
// AddIdentity adds identity into the known identities list (for message decryption).
|
||||
func (w *Whisper) AddIdentity(key *ecdsa.PrivateKey) {
|
||||
w.keyMu.Lock()
|
||||
defer w.keyMu.Unlock()
|
||||
w.privateKeys[common.ToHex(crypto.FromECDSAPub(&key.PublicKey))] = key
|
||||
}
|
||||
|
||||
// InjectIdentity injects a manually added identity/key pair into the whisper keys
|
||||
func (w *Whisper) InjectIdentity(key *ecdsa.PrivateKey) error {
|
||||
if w.HasIdentity(common.ToHex(crypto.FromECDSAPub(&key.PublicKey))) { // no need to re-inject
|
||||
return nil
|
||||
}
|
||||
w.keyMu.Lock()
|
||||
defer w.keyMu.Unlock()
|
||||
|
||||
w.privateKeys = make(map[string]*ecdsa.PrivateKey) // reset key store
|
||||
w.privateKeys[common.ToHex(crypto.FromECDSAPub(&key.PublicKey))] = key
|
||||
|
||||
glog.V(logger.Info).Infof("Injected identity into whisper: %s\n", common.ToHex(crypto.FromECDSAPub(&key.PublicKey)))
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClearIdentities clears the current whisper identities in memory
|
||||
func (w *Whisper) ClearIdentities() error {
|
||||
w.keyMu.Lock()
|
||||
defer w.keyMu.Unlock()
|
||||
|
||||
w.privateKeys = make(map[string]*ecdsa.PrivateKey)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *Whisper) GenerateSymKey(name string) error {
|
||||
const size = aesKeyLength * 2
|
||||
buf := make([]byte, size)
|
||||
|
|
Loading…
Reference in New Issue