mirror of
https://github.com/status-im/status-go.git
synced 2025-02-27 14:10:54 +00:00
- API is async - Node manager, backend and API modules have more that 90% coverage - For each level (node manager, backend, public API) random testing was used to ensure that we don't have race conditions
742 lines
22 KiB
Go
742 lines
22 KiB
Go
package api_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
gethcommon "github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
"github.com/ethereum/go-ethereum/log"
|
|
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
|
|
"github.com/status-im/status-go/geth/common"
|
|
"github.com/status-im/status-go/geth/jail"
|
|
"github.com/status-im/status-go/geth/node"
|
|
"github.com/status-im/status-go/geth/params"
|
|
. "github.com/status-im/status-go/geth/testing"
|
|
"github.com/status-im/status-go/static"
|
|
)
|
|
|
|
const (
|
|
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)`
|
|
txSendFolder = "testdata/jail/tx-send/"
|
|
testChatID = "testChat"
|
|
)
|
|
|
|
func (s *BackendTestSuite) TestJailContractDeployment() {
|
|
require := s.Require()
|
|
require.NotNil(s.backend)
|
|
|
|
s.StartTestBackend(params.RopstenNetworkID)
|
|
defer s.StopTestBackend()
|
|
|
|
time.Sleep(TestConfig.Node.SyncSeconds * time.Second) // allow to sync
|
|
|
|
jailInstance := s.backend.JailManager()
|
|
require.NotNil(jailInstance)
|
|
|
|
jailInstance.Parse(testChatID, "")
|
|
|
|
// obtain VM for a given chat (to send custom JS to jailed version of Send())
|
|
vm, err := jailInstance.JailCellVM(testChatID)
|
|
require.NoError(err)
|
|
|
|
// make sure you panic if transaction complete doesn't return
|
|
completeQueuedTransaction := make(chan struct{}, 1)
|
|
common.PanicAfter(30*time.Second, completeQueuedTransaction, s.T().Name())
|
|
|
|
// replace transaction notification handler
|
|
var txHash gethcommon.Hash
|
|
node.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
|
var envelope node.SignalEnvelope
|
|
err := json.Unmarshal([]byte(jsonEvent), &envelope)
|
|
s.NoError(err, fmt.Sprintf("cannot unmarshal JSON: %s", jsonEvent))
|
|
|
|
if envelope.Type == node.EventTransactionQueued {
|
|
event := envelope.Event.(map[string]interface{})
|
|
log.Info("transaction queued (will be completed shortly)", "id", event["id"].(string))
|
|
|
|
//t.Logf("Transaction queued (will be completed shortly): {id: %s}\n", event["id"].(string))
|
|
|
|
s.NoError(s.backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
|
|
|
|
var err error
|
|
txHash, err = s.backend.CompleteTransaction(event["id"].(string), TestConfig.Account1.Password)
|
|
s.NoError(err, fmt.Sprintf("cannot complete queued transaction[%v]", event["id"]))
|
|
|
|
log.Info("contract transaction complete", "URL", "https://rinkeby.etherscan.io/tx/"+txHash.Hex())
|
|
close(completeQueuedTransaction)
|
|
}
|
|
})
|
|
|
|
_, err = vm.Run(`
|
|
var responseValue = null;
|
|
var testContract = web3.eth.contract([{"constant":true,"inputs":[{"name":"a","type":"int256"}],"name":"double","outputs":[{"name":"","type":"int256"}],"payable":false,"type":"function"}]);
|
|
var test = testContract.new(
|
|
{
|
|
from: '` + TestConfig.Account1.Address + `',
|
|
data: '0x6060604052341561000c57fe5b5b60a58061001b6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636ffa1caa14603a575bfe5b3415604157fe5b60556004808035906020019091905050606b565b6040518082815260200191505060405180910390f35b60008160020290505b9190505600a165627a7a72305820ccdadd737e4ac7039963b54cee5e5afb25fa859a275252bdcf06f653155228210029',
|
|
gas: '` + strconv.Itoa(params.DefaultGas) + `'
|
|
}, function (e, contract){
|
|
if (!e) {
|
|
responseValue = contract.transactionHash
|
|
}
|
|
})
|
|
`)
|
|
require.NoError(err)
|
|
|
|
<-completeQueuedTransaction
|
|
|
|
responseValue, err := vm.Get("responseValue")
|
|
require.NoError(err, "vm.Get() failed")
|
|
|
|
response, err := responseValue.ToString()
|
|
require.NoError(err, "cannot parse result")
|
|
|
|
expectedResponse := txHash.Hex()
|
|
require.Equal(expectedResponse, response, "expected response is not returned")
|
|
}
|
|
|
|
func (s *BackendTestSuite) TestJailSendQueuedTransaction() {
|
|
require := s.Require()
|
|
require.NotNil(s.backend)
|
|
|
|
s.StartTestBackend(params.RopstenNetworkID)
|
|
defer s.StopTestBackend()
|
|
|
|
time.Sleep(TestConfig.Node.SyncSeconds * time.Second) // allow to sync
|
|
|
|
jailInstance := s.backend.JailManager()
|
|
require.NotNil(jailInstance)
|
|
|
|
// log into account from which transactions will be sent
|
|
require.NoError(s.backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
|
|
|
|
txParams := `{
|
|
"from": "` + TestConfig.Account1.Address + `",
|
|
"to": "0xf82da7547534045b4e00442bc89e16186cf8c272",
|
|
"value": "0.000001"
|
|
}`
|
|
|
|
txCompletedSuccessfully := make(chan struct{})
|
|
txCompletedCounter := make(chan struct{})
|
|
txHashes := make(chan gethcommon.Hash)
|
|
|
|
// replace transaction notification handler
|
|
requireMessageId := false
|
|
node.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
|
var envelope node.SignalEnvelope
|
|
err := json.Unmarshal([]byte(jsonEvent), &envelope)
|
|
s.NoError(err, fmt.Sprintf("cannot unmarshal JSON: %s", jsonEvent))
|
|
|
|
if envelope.Type == node.EventTransactionQueued {
|
|
event := envelope.Event.(map[string]interface{})
|
|
messageId, ok := event["message_id"].(string)
|
|
s.True(ok, "Message id is required, but not found")
|
|
if requireMessageId {
|
|
if len(messageId) == 0 {
|
|
s.Fail("Message id is required, but not provided")
|
|
return
|
|
}
|
|
} else {
|
|
if len(messageId) != 0 {
|
|
s.Fail("Message id is not required, but provided")
|
|
return
|
|
}
|
|
}
|
|
log.Info("Transaction queued (will be completed shortly)", "id", event["id"].(string))
|
|
|
|
var txHash gethcommon.Hash
|
|
if txHash, err = s.backend.CompleteTransaction(event["id"].(string), TestConfig.Account1.Password); err != nil {
|
|
s.Fail(fmt.Sprintf("cannot complete queued transaction[%v]: %v", event["id"], err))
|
|
} else {
|
|
log.Info("Transaction complete", "URL", "https://rinkeby.etherscan.io/tx/%s"+txHash.Hex())
|
|
}
|
|
|
|
txCompletedSuccessfully <- struct{}{} // so that timeout is aborted
|
|
txHashes <- txHash
|
|
txCompletedCounter <- struct{}{}
|
|
}
|
|
})
|
|
|
|
type testCommand struct {
|
|
command string
|
|
params string
|
|
expectedResponse string
|
|
}
|
|
type testCase struct {
|
|
name string
|
|
file string
|
|
requireMessageId bool
|
|
commands []testCommand
|
|
}
|
|
|
|
tests := []testCase{
|
|
{
|
|
// no context or message id
|
|
name: "Case 1: no message id or context in inited JS",
|
|
file: "no-message-id-or-context.js",
|
|
requireMessageId: false,
|
|
commands: []testCommand{
|
|
{
|
|
`["commands", "send"]`,
|
|
txParams,
|
|
`{"result": {"transaction-hash":"TX_HASH"}}`,
|
|
},
|
|
{
|
|
`["commands", "getBalance"]`,
|
|
`{"address": "` + TestConfig.Account1.Address + `"}`,
|
|
`{"result": {"balance":42}}`,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
// context is present in inited JS (but no message id is there)
|
|
name: "Case 2: context is present in inited JS (but no message id is there)",
|
|
file: "context-no-message-id.js",
|
|
requireMessageId: false,
|
|
commands: []testCommand{
|
|
{
|
|
`["commands", "send"]`,
|
|
txParams,
|
|
`{"result": {"context":{"` + jail.SendTransactionRequest + `":true},"result":{"transaction-hash":"TX_HASH"}}}`,
|
|
},
|
|
{
|
|
`["commands", "getBalance"]`,
|
|
`{"address": "` + TestConfig.Account1.Address + `"}`,
|
|
`{"result": {"context":{},"result":{"balance":42}}}`, // note empty (but present) context!
|
|
},
|
|
},
|
|
},
|
|
{
|
|
// message id is present in inited JS, but no context is there
|
|
name: "Case 3: message id is present, context is not present",
|
|
file: "message-id-no-context.js",
|
|
requireMessageId: true,
|
|
commands: []testCommand{
|
|
{
|
|
`["commands", "send"]`,
|
|
txParams,
|
|
`{"result": {"transaction-hash":"TX_HASH"}}`,
|
|
},
|
|
{
|
|
`["commands", "getBalance"]`,
|
|
`{"address": "` + TestConfig.Account1.Address + `"}`,
|
|
`{"result": {"balance":42}}`, // note empty context!
|
|
},
|
|
},
|
|
},
|
|
{
|
|
// both message id and context are present in inited JS (this UC is what we normally expect to see)
|
|
name: "Case 4: both message id and context are present",
|
|
file: "tx-send.js",
|
|
requireMessageId: true,
|
|
commands: []testCommand{
|
|
{
|
|
`["commands", "send"]`,
|
|
txParams,
|
|
`{"result": {"context":{"eth_sendTransaction":true,"message_id":"foobar"},"result":{"transaction-hash":"TX_HASH"}}}`,
|
|
},
|
|
{
|
|
`["commands", "getBalance"]`,
|
|
`{"address": "` + TestConfig.Account1.Address + `"}`,
|
|
`{"result": {"context":{"message_id":"42"},"result":{"balance":42}}}`, // message id in context, but default one is used!
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
|
|
jailInstance.BaseJS(string(static.MustAsset(txSendFolder + test.file)))
|
|
common.PanicAfter(60*time.Second, txCompletedSuccessfully, test.name)
|
|
jailInstance.Parse(testChatID, ``)
|
|
|
|
requireMessageId = test.requireMessageId
|
|
|
|
for _, command := range test.commands {
|
|
go func(jail common.JailManager, test testCase, command testCommand) {
|
|
log.Info(fmt.Sprintf("->%s: %s", test.name, command.command))
|
|
response := jail.Call(testChatID, command.command, command.params)
|
|
var txHash gethcommon.Hash
|
|
if command.command == `["commands", "send"]` {
|
|
txHash = <-txHashes
|
|
}
|
|
expectedResponse := strings.Replace(command.expectedResponse, "TX_HASH", txHash.Hex(), 1)
|
|
s.Equal(expectedResponse, response)
|
|
}(jailInstance, test, command)
|
|
}
|
|
<-txCompletedCounter
|
|
}
|
|
}
|
|
|
|
//
|
|
func (s *BackendTestSuite) TestGasEstimation() {
|
|
require := s.Require()
|
|
require.NotNil(s.backend)
|
|
|
|
s.StartTestBackend(params.RopstenNetworkID)
|
|
defer s.StopTestBackend()
|
|
|
|
jailInstance := s.backend.JailManager()
|
|
require.NotNil(jailInstance)
|
|
jailInstance.Parse(testChatID, "")
|
|
|
|
// obtain VM for a given chat (to send custom JS to jailed version of Send())
|
|
vm, err := jailInstance.JailCellVM(testChatID)
|
|
require.NoError(err)
|
|
|
|
// make sure you panic if transaction complete doesn't return
|
|
completeQueuedTransaction := make(chan struct{}, 1)
|
|
common.PanicAfter(30*time.Second, completeQueuedTransaction, s.T().Name())
|
|
|
|
// replace transaction notification handler
|
|
var txHash gethcommon.Hash
|
|
node.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
|
var envelope node.SignalEnvelope
|
|
err := json.Unmarshal([]byte(jsonEvent), &envelope)
|
|
s.NoError(err, fmt.Sprintf("cannot unmarshal JSON: %s", jsonEvent))
|
|
|
|
if envelope.Type == node.EventTransactionQueued {
|
|
event := envelope.Event.(map[string]interface{})
|
|
log.Info("transaction queued (will be completed shortly)", "id", event["id"].(string))
|
|
|
|
//t.Logf("Transaction queued (will be completed shortly): {id: %s}\n", event["id"].(string))
|
|
|
|
s.NoError(s.backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
|
|
|
|
var err error
|
|
txHash, err = s.backend.CompleteTransaction(event["id"].(string), TestConfig.Account1.Password)
|
|
s.NoError(err, fmt.Sprintf("cannot complete queued transaction[%v]", event["id"]))
|
|
|
|
log.Info("contract transaction complete", "URL", "https://rinkeby.etherscan.io/tx/"+txHash.Hex())
|
|
close(completeQueuedTransaction)
|
|
}
|
|
})
|
|
|
|
_, err = vm.Run(`
|
|
var responseValue = null;
|
|
var testContract = web3.eth.contract([{"constant":true,"inputs":[{"name":"a","type":"int256"}],"name":"double","outputs":[{"name":"","type":"int256"}],"payable":false,"type":"function"}]);
|
|
var test = testContract.new(
|
|
{
|
|
from: '` + TestConfig.Account1.Address + `',
|
|
data: '0x6060604052341561000c57fe5b5b60a58061001b6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636ffa1caa14603a575bfe5b3415604157fe5b60556004808035906020019091905050606b565b6040518082815260200191505060405180910390f35b60008160020290505b9190505600a165627a7a72305820ccdadd737e4ac7039963b54cee5e5afb25fa859a275252bdcf06f653155228210029',
|
|
}, function (e, contract){
|
|
if (!e) {
|
|
responseValue = contract.transactionHash
|
|
}
|
|
})
|
|
`)
|
|
s.NoError(err)
|
|
|
|
<-completeQueuedTransaction
|
|
|
|
responseValue, err := vm.Get("responseValue")
|
|
s.NoError(err, "vm.Get() failed")
|
|
|
|
response, err := responseValue.ToString()
|
|
s.NoError(err, "cannot parse result")
|
|
|
|
expectedResponse := txHash.Hex()
|
|
s.Equal(expectedResponse, response, "expected response is not returned")
|
|
s.T().Logf("estimation complete: %s", response)
|
|
}
|
|
|
|
func (s *BackendTestSuite) TestJailWhisper() {
|
|
require := s.Require()
|
|
require.NotNil(s.backend)
|
|
|
|
s.StartTestBackend(params.RopstenNetworkID)
|
|
defer s.StopTestBackend()
|
|
|
|
jailInstance := s.backend.JailManager()
|
|
require.NotNil(jailInstance)
|
|
|
|
whisperService := s.WhisperService()
|
|
whisperAPI := whisper.NewPublicWhisperAPI(whisperService)
|
|
|
|
accountManager := s.backend.AccountManager()
|
|
|
|
// account1
|
|
_, accountKey1, err := accountManager.AddressToDecryptedAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
|
|
require.NoError(err)
|
|
accountKey1Hex := gethcommon.ToHex(crypto.FromECDSAPub(&accountKey1.PrivateKey.PublicKey))
|
|
|
|
_, err = whisperService.AddKeyPair(accountKey1.PrivateKey)
|
|
require.NoError(err, fmt.Sprintf("identity not injected: %v", accountKey1Hex))
|
|
|
|
if ok, err := whisperAPI.HasKeyPair(accountKey1Hex); err != nil || !ok {
|
|
require.FailNow(fmt.Sprintf("identity not injected: %v", accountKey1Hex))
|
|
}
|
|
|
|
// account2
|
|
_, accountKey2, err := accountManager.AddressToDecryptedAccount(TestConfig.Account2.Address, TestConfig.Account2.Password)
|
|
require.NoError(err)
|
|
accountKey2Hex := gethcommon.ToHex(crypto.FromECDSAPub(&accountKey2.PrivateKey.PublicKey))
|
|
|
|
_, err = whisperService.AddKeyPair(accountKey2.PrivateKey)
|
|
require.NoError(err, fmt.Sprintf("identity not injected: %v", accountKey2Hex))
|
|
|
|
if ok, err := whisperAPI.HasKeyPair(accountKey2Hex); err != nil || !ok {
|
|
require.FailNow(fmt.Sprintf("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: "",
|
|
}
|
|
|
|
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.hasKeyPair(identity1)) {
|
|
throw 'idenitity "` + accountKey1Hex + `" not found in whisper';
|
|
}
|
|
|
|
var identity2 = '` + accountKey2Hex + `';
|
|
if (!web3.shh.hasKeyPair(identity2)) {
|
|
throw 'idenitity "` + accountKey2Hex + `" not found in whisper';
|
|
}
|
|
|
|
var topic = makeTopic();
|
|
var payload = '` + whisperMessage1 + `';
|
|
|
|
// start watching for messages
|
|
var filter = shh.filter({
|
|
type: "asym",
|
|
sig: identity1,
|
|
key: identity2,
|
|
topics: [topic]
|
|
});
|
|
console.log(JSON.stringify(filter));
|
|
|
|
// post message
|
|
var message = {
|
|
type: "asym",
|
|
sig: identity1,
|
|
key: identity2,
|
|
topic: 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.hasKeyPair(identity)) {
|
|
throw 'idenitity "` + accountKey1Hex + `" not found in whisper';
|
|
}
|
|
|
|
var topic = makeTopic();
|
|
var payload = '` + whisperMessage2 + `';
|
|
|
|
// start watching for messages
|
|
var filter = shh.filter({
|
|
type: "asym",
|
|
sig: identity,
|
|
key: identity,
|
|
topics: [topic],
|
|
});
|
|
|
|
// post message
|
|
var message = {
|
|
type: "asym",
|
|
sig: identity,
|
|
key: identity,
|
|
topic: 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.hasKeyPair(identity)) {
|
|
throw 'idenitity "` + accountKey1Hex + `" not found in whisper';
|
|
}
|
|
|
|
var topic = makeTopic();
|
|
var payload = '` + whisperMessage3 + `';
|
|
|
|
// generate symmetric key
|
|
var keyid = shh.generateSymmetricKey();
|
|
if (!shh.hasSymmetricKey(keyid)) {
|
|
throw new Error('key not found');
|
|
}
|
|
|
|
// start watching for messages
|
|
var filter = shh.filter({
|
|
type: "sym",
|
|
sig: identity,
|
|
topics: [topic],
|
|
key: keyid
|
|
});
|
|
|
|
// post message
|
|
var message = {
|
|
type: "sym",
|
|
sig: identity,
|
|
topic: topic,
|
|
payload: payload,
|
|
ttl: 20,
|
|
key: keyid
|
|
};
|
|
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 = makeTopic();
|
|
var payload = '` + whisperMessage4 + `';
|
|
|
|
// generate symmetric key
|
|
var keyid = shh.generateSymmetricKey();
|
|
if (!shh.hasSymmetricKey(keyid)) {
|
|
throw new Error('key not found');
|
|
}
|
|
|
|
// start watching for messages
|
|
var filter = shh.filter({
|
|
type: "sym",
|
|
topics: [topic],
|
|
key: keyid
|
|
});
|
|
|
|
// post message
|
|
var message = {
|
|
type: "sym",
|
|
topic: topic,
|
|
payload: payload,
|
|
ttl: 20,
|
|
key: keyid
|
|
};
|
|
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.hasKeyPair(identity)) {
|
|
throw 'idenitity "` + accountKey2Hex + `" not found in whisper';
|
|
}
|
|
|
|
var topic = makeTopic();
|
|
var payload = '` + whisperMessage5 + `';
|
|
|
|
// start watching for messages
|
|
var filter = shh.filter({
|
|
type: "asym",
|
|
key: identity,
|
|
topics: [topic],
|
|
});
|
|
|
|
// post message
|
|
var message = {
|
|
type: "asym",
|
|
key: identity,
|
|
topic: 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.hasKeyPair(identity1)) {
|
|
throw 'idenitity "` + accountKey1Hex + `" not found in whisper';
|
|
}
|
|
|
|
var identity2 = '` + accountKey2Hex + `';
|
|
if (!web3.shh.hasKeyPair(identity2)) {
|
|
throw 'idenitity "` + accountKey2Hex + `" not found in whisper';
|
|
}
|
|
|
|
var topic = makeTopic();
|
|
var payload = '` + whisperMessage6 + `';
|
|
|
|
// start watching for messages
|
|
var filter = shh.filter({
|
|
type: "asym",
|
|
sig: identity2,
|
|
key: identity1,
|
|
topics: [topic]
|
|
});
|
|
|
|
// post message
|
|
var message = {
|
|
type: "asym",
|
|
sig: identity2,
|
|
key: identity1,
|
|
topic: 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 {
|
|
s.T().Log(testCase.name)
|
|
testCaseKey := crypto.Keccak256Hash([]byte(testCase.name)).Hex()
|
|
jailInstance.Parse(testCaseKey, `
|
|
var shh = web3.shh;
|
|
var makeTopic = function () {
|
|
var min = 1;
|
|
var max = Math.pow(16, 8);
|
|
var randInt = Math.floor(Math.random() * (max - min + 1)) + min;
|
|
return web3.toHex(randInt);
|
|
};
|
|
`)
|
|
vm, err := jailInstance.JailCellVM(testCaseKey)
|
|
require.NoError(err, "cannot get VM")
|
|
|
|
// post messages
|
|
if _, err := vm.Run(testCase.testCode); err != nil {
|
|
require.Fail(err.Error())
|
|
return
|
|
}
|
|
|
|
if !testCase.useFilter {
|
|
continue
|
|
}
|
|
|
|
// update installed filters
|
|
filterId, err := vm.Get("filterId")
|
|
require.NoError(err, "cannot get filterId")
|
|
|
|
filterName, err := vm.Get("filterName")
|
|
require.NoError(err, "cannot get filterName")
|
|
|
|
if _, ok := installedFilters[filterName.String()]; !ok {
|
|
require.FailNow("unrecognized filter")
|
|
}
|
|
|
|
installedFilters[filterName.String()] = filterId.String()
|
|
}
|
|
|
|
time.Sleep(2 * time.Second) // allow whisper to poll
|
|
|
|
for testKey, filter := range installedFilters {
|
|
if filter != "" {
|
|
s.T().Logf("filter found: %v", filter)
|
|
for _, message := range whisperAPI.GetNewSubscriptionMessages(filter) {
|
|
s.T().Logf("message found: %s", gethcommon.FromHex(message.Payload))
|
|
passedTests[testKey] = true
|
|
}
|
|
}
|
|
}
|
|
|
|
for testName, passedTest := range passedTests {
|
|
if !passedTest {
|
|
s.Fail(fmt.Sprintf("test not passed: %v", testName))
|
|
}
|
|
}
|
|
}
|