Merge pull request #123 from farazdagi/feature/node-settings
Feature/node settings
This commit is contained in:
commit
053fb6b8a7
18
Makefile
18
Makefile
|
@ -49,14 +49,17 @@ statusgo-ios-simulator-mainnet: xgo
|
|||
|
||||
ci:
|
||||
build/env.sh go test -v -cover ./geth
|
||||
build/env.sh go test -v -cover ./jail
|
||||
build/env.sh go test -v -cover ./geth/params
|
||||
build/env.sh go test -v -cover ./geth/jail
|
||||
build/env.sh go test -v -cover ./extkeys
|
||||
|
||||
test-all:
|
||||
test:
|
||||
@build/env.sh echo "mode: set" > coverage-all.out
|
||||
build/env.sh go test -coverprofile=coverage.out -covermode=set ./geth
|
||||
@build/env.sh tail -n +2 coverage.out >> coverage-all.out
|
||||
build/env.sh go test -coverprofile=coverage.out -covermode=set ./jail
|
||||
build/env.sh go test -coverprofile=coverage.out -covermode=set ./geth/params
|
||||
@build/env.sh tail -n +2 coverage.out >> coverage-all.out
|
||||
build/env.sh go test -coverprofile=coverage.out -covermode=set ./geth/jail
|
||||
@build/env.sh tail -n +2 coverage.out >> coverage-all.out
|
||||
build/env.sh go test -coverprofile=coverage.out -covermode=set ./extkeys
|
||||
@build/env.sh tail -n +2 coverage.out >> coverage-all.out
|
||||
|
@ -65,15 +68,18 @@ test-all:
|
|||
@build/env.sh go tool cover -html=coverage-all.out -o coverage.html
|
||||
@build/env.sh go tool cover -func=coverage-all.out
|
||||
|
||||
test: test-all
|
||||
|
||||
test-geth:
|
||||
build/env.sh go test -v -coverprofile=coverage.out ./geth
|
||||
@build/env.sh go tool cover -html=coverage.out -o coverage.html
|
||||
@build/env.sh go tool cover -func=coverage.out
|
||||
|
||||
test-config:
|
||||
build/env.sh go test -v -coverprofile=coverage.out ./geth/params
|
||||
@build/env.sh go tool cover -html=coverage.out -o coverage.html
|
||||
@build/env.sh go tool cover -func=coverage.out
|
||||
|
||||
test-jail:
|
||||
build/env.sh go test -v -coverprofile=coverage.out ./jail
|
||||
build/env.sh go test -v -coverprofile=coverage.out ./geth/jail
|
||||
@build/env.sh go tool cover -html=coverage.out -o coverage.html
|
||||
@build/env.sh go tool cover -func=coverage.out
|
||||
|
||||
|
|
|
@ -9,5 +9,5 @@ fi
|
|||
|
||||
# set gitCommit when running from a Git checkout.
|
||||
if [ -f ".git/HEAD" ]; then
|
||||
echo "-ldflags '-X github.com/status-im/status-go/geth.UseTestnetFlag=false -X main.buildStamp=`date -u '+%Y-%m-%d.%H:%M:%S'` -X main.gitCommit=$(git rev-parse HEAD)'";
|
||||
echo "-ldflags '-X github.com/status-im/status-go/geth/params.UseMainnetFlag=true -X main.buildStamp=`date -u '+%Y-%m-%d.%H:%M:%S'` -X main.gitCommit=$(git rev-parse HEAD)'";
|
||||
fi
|
||||
|
|
|
@ -9,5 +9,5 @@ fi
|
|||
|
||||
# set gitCommit when running from a Git checkout.
|
||||
if [ -f ".git/HEAD" ]; then
|
||||
echo "-ldflags '-X github.com/status-im/status-go/geth.UseTestnetFlag=true -X main.buildStamp=`date -u '+%Y-%m-%d.%H:%M:%S'` -X main.gitCommit=$(git rev-parse HEAD)'";
|
||||
echo "-ldflags '-X github.com/status-im/status-go/geth/params.UseMainnetFlag=false -X main.buildStamp=`date -u '+%Y-%m-%d.%H:%M:%S'` -X main.gitCommit=$(git rev-parse HEAD)'";
|
||||
fi
|
||||
|
|
|
@ -8,7 +8,8 @@ import (
|
|||
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv2"
|
||||
"github.com/status-im/status-go/geth"
|
||||
"github.com/status-im/status-go/jail"
|
||||
"github.com/status-im/status-go/geth/jail"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
//export CreateAccount
|
||||
|
@ -197,18 +198,29 @@ func DiscardTransactions(ids *C.char) *C.char {
|
|||
return C.CString(string(outBytes))
|
||||
}
|
||||
|
||||
//export StartNode
|
||||
func StartNode(datadir *C.char) *C.char {
|
||||
// This starts a geth node with the given datadir
|
||||
err := geth.CreateAndRunNode(&geth.NodeConfig{
|
||||
DataDir: C.GoString(datadir),
|
||||
IPCEnabled: false,
|
||||
HTTPPort: geth.HTTPPort,
|
||||
WSEnabled: false,
|
||||
WSPort: geth.WSPort,
|
||||
TLSEnabled: false,
|
||||
})
|
||||
//export GenerateConfig
|
||||
func GenerateConfig(datadir *C.char, networkId C.int) *C.char {
|
||||
config, err := params.NewNodeConfig(C.GoString(datadir), int(networkId))
|
||||
if err != nil {
|
||||
return makeJSONErrorResponse(err)
|
||||
}
|
||||
|
||||
outBytes, err := json.Marshal(&config)
|
||||
if err != nil {
|
||||
return makeJSONErrorResponse(err)
|
||||
}
|
||||
|
||||
return C.CString(string(outBytes))
|
||||
}
|
||||
|
||||
//export StartNode
|
||||
func StartNode(configJSON *C.char) *C.char {
|
||||
config, err := params.LoadNodeConfig(C.GoString(configJSON))
|
||||
if err != nil {
|
||||
return makeJSONErrorResponse(err)
|
||||
}
|
||||
|
||||
err = geth.CreateAndRunNode(config)
|
||||
return makeJSONErrorResponse(err)
|
||||
}
|
||||
|
||||
|
@ -230,19 +242,6 @@ func ResetChainData() *C.char {
|
|||
return makeJSONErrorResponse(err)
|
||||
}
|
||||
|
||||
//export StartTLSNode
|
||||
func StartTLSNode(datadir *C.char) *C.char {
|
||||
// This starts a geth node with the given datadir
|
||||
err := geth.CreateAndRunNode(&geth.NodeConfig{
|
||||
DataDir: C.GoString(datadir),
|
||||
HTTPPort: geth.HTTPPort,
|
||||
WSPort: geth.WSPort,
|
||||
TLSEnabled: true,
|
||||
})
|
||||
|
||||
return makeJSONErrorResponse(err)
|
||||
}
|
||||
|
||||
//export StopNodeRPCServer
|
||||
func StopNodeRPCServer() *C.char {
|
||||
_, err := geth.NodeManagerInstance().StopNodeRPCServer()
|
||||
|
|
|
@ -2,7 +2,6 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/status-im/status-go/geth"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
|
@ -12,10 +11,16 @@ var (
|
|||
)
|
||||
|
||||
func main() {
|
||||
nodeConfig, err := params.NewNodeConfig(".ethereumcmd", params.TestNetworkId)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
netVersion := "mainnet"
|
||||
if geth.UseTestnet {
|
||||
if nodeConfig.TestNet {
|
||||
netVersion = "testnet"
|
||||
}
|
||||
|
||||
fmt.Printf("%s\nVersion: %s\nGit Commit: %s\nBuild Date: %s\nNetwork: %s\n",
|
||||
geth.ClientIdentifier, params.Version, gitCommit, buildStamp, netVersion)
|
||||
nodeConfig.Name, params.Version, gitCommit, buildStamp, netVersion)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -14,18 +15,18 @@ import (
|
|||
"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"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
const (
|
||||
testDataDir = "../../.ethereumtest"
|
||||
testNodeSyncSeconds = 30
|
||||
testAddress = "0xadaf150b905cf5e6a778e553e15a139b6618bbb7"
|
||||
testAddressPassword = "asdfasdf"
|
||||
newAccountPassword = "badpassword"
|
||||
testAddress1 = "0xadd4d1d02e71c7360c53296968e59d57fd15e2ba"
|
||||
testStatusJsFile = "../../jail/testdata/status.js"
|
||||
)
|
||||
var testConfig *geth.TestConfig
|
||||
|
||||
func init() {
|
||||
// error is ignored, as it will occur on non-test compilation only, and there testConfig is not used at all
|
||||
// (we have to use "main" package due to restrictions on including C imports into *_test packages)
|
||||
testConfig, _ = geth.LoadTestConfig()
|
||||
}
|
||||
|
||||
func testExportedAPI(t *testing.T, done chan struct{}) {
|
||||
<-startTestNode(t)
|
||||
|
@ -34,6 +35,10 @@ func testExportedAPI(t *testing.T, done chan struct{}) {
|
|||
name string
|
||||
fn func(t *testing.T) bool
|
||||
}{
|
||||
{
|
||||
"check default configuration",
|
||||
testGetDefaultConfig,
|
||||
},
|
||||
{
|
||||
"reset blockchain data",
|
||||
testResetChainData,
|
||||
|
@ -97,6 +102,97 @@ func testExportedAPI(t *testing.T, done chan struct{}) {
|
|||
done <- struct{}{}
|
||||
}
|
||||
|
||||
func testGetDefaultConfig(t *testing.T) bool {
|
||||
// test Mainnet config
|
||||
nodeConfig := params.NodeConfig{}
|
||||
|
||||
rawResponse := GenerateConfig(C.CString("/tmp/data-folder"), 1)
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &nodeConfig); err != nil {
|
||||
t.Errorf("cannot decode reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
return false
|
||||
}
|
||||
|
||||
chainConfig := nodeConfig.ChainConfig
|
||||
if chainConfig.HomesteadBlock.Cmp(gethparams.MainNetHomesteadBlock) != 0 {
|
||||
t.Error("invalid chainConfig.HomesteadBlock")
|
||||
return false
|
||||
}
|
||||
if chainConfig.DAOForkBlock.Cmp(gethparams.MainNetDAOForkBlock) != 0 {
|
||||
t.Error("invalid chainConfig.DAOForkBlock")
|
||||
return false
|
||||
}
|
||||
if chainConfig.DAOForkSupport != true {
|
||||
t.Error("invalid chainConfig.DAOForkSupport")
|
||||
return false
|
||||
}
|
||||
if chainConfig.EIP150Block.Cmp(gethparams.MainNetHomesteadGasRepriceBlock) != 0 {
|
||||
t.Error("invalid chainConfig.EIP150Block")
|
||||
return false
|
||||
}
|
||||
if chainConfig.EIP150Hash != gethparams.MainNetHomesteadGasRepriceHash {
|
||||
t.Error("invalid chainConfig.EIP150Hash")
|
||||
return false
|
||||
}
|
||||
if chainConfig.EIP155Block.Cmp(gethparams.MainNetSpuriousDragon) != 0 {
|
||||
t.Error("invalid chainConfig.EIP155Block")
|
||||
return false
|
||||
}
|
||||
if chainConfig.EIP158Block.Cmp(gethparams.MainNetSpuriousDragon) != 0 {
|
||||
t.Error("invalid chainConfig.EIP158Block")
|
||||
return false
|
||||
}
|
||||
if chainConfig.ChainId.Cmp(gethparams.MainNetChainID) != 0 {
|
||||
t.Error("invalid chainConfig.ChainId")
|
||||
return false
|
||||
}
|
||||
|
||||
// test Testnet
|
||||
nodeConfig = params.NodeConfig{}
|
||||
rawResponse = GenerateConfig(C.CString("/tmp/data-folder"), 3)
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &nodeConfig); err != nil {
|
||||
t.Errorf("cannot decode reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
return false
|
||||
}
|
||||
|
||||
chainConfig = nodeConfig.ChainConfig
|
||||
refChainConfig := gethparams.TestnetChainConfig
|
||||
|
||||
if chainConfig.HomesteadBlock.Cmp(refChainConfig.HomesteadBlock) != 0 {
|
||||
t.Error("invalid chainConfig.HomesteadBlock")
|
||||
return false
|
||||
}
|
||||
if chainConfig.DAOForkBlock != nil { // already forked
|
||||
t.Error("invalid chainConfig.DAOForkBlock")
|
||||
return false
|
||||
}
|
||||
if chainConfig.DAOForkSupport != refChainConfig.DAOForkSupport {
|
||||
t.Error("invalid chainConfig.DAOForkSupport")
|
||||
return false
|
||||
}
|
||||
if chainConfig.EIP150Block.Cmp(refChainConfig.EIP150Block) != 0 {
|
||||
t.Error("invalid chainConfig.EIP150Block")
|
||||
return false
|
||||
}
|
||||
if chainConfig.EIP150Hash != refChainConfig.EIP150Hash {
|
||||
t.Error("invalid chainConfig.EIP150Hash")
|
||||
return false
|
||||
}
|
||||
if chainConfig.EIP155Block.Cmp(refChainConfig.EIP155Block) != 0 {
|
||||
t.Error("invalid chainConfig.EIP155Block")
|
||||
return false
|
||||
}
|
||||
if chainConfig.EIP158Block.Cmp(refChainConfig.EIP158Block) != 0 {
|
||||
t.Error("invalid chainConfig.EIP158Block")
|
||||
return false
|
||||
}
|
||||
if chainConfig.ChainId.Cmp(refChainConfig.ChainId) != 0 {
|
||||
t.Error("invalid chainConfig.ChainId")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func testResetChainData(t *testing.T) bool {
|
||||
resetChainDataResponse := geth.JSONError{}
|
||||
rawResponse := ResetChainData()
|
||||
|
@ -110,7 +206,7 @@ func testResetChainData(t *testing.T) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
time.Sleep(testNodeSyncSeconds * time.Second) // allow to re-sync blockchain
|
||||
time.Sleep(testConfig.Node.SyncSeconds * time.Second) // allow to re-sync blockchain
|
||||
|
||||
testCompleteTransaction(t)
|
||||
|
||||
|
@ -126,7 +222,7 @@ func testStopResumeNode(t *testing.T) bool {
|
|||
}
|
||||
|
||||
// create an account
|
||||
address1, pubKey1, _, err := geth.CreateAccount(newAccountPassword)
|
||||
address1, pubKey1, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return false
|
||||
|
@ -140,7 +236,7 @@ func testStopResumeNode(t *testing.T) bool {
|
|||
|
||||
// select account
|
||||
loginResponse := geth.JSONError{}
|
||||
rawResponse := Login(C.CString(address1), C.CString(newAccountPassword))
|
||||
rawResponse := Login(C.CString(address1), C.CString(testConfig.Account1.Password))
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &loginResponse); err != nil {
|
||||
t.Errorf("cannot decode RecoverAccount reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -245,7 +341,7 @@ func testRestartNodeRPC(t *testing.T) bool {
|
|||
t.Errorf("cannot decode StartNodeRPCServer reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
return false
|
||||
}
|
||||
expectedError := "HTTP RPC already running on localhost:8545"
|
||||
expectedError := "HTTP RPC already running on localhost:8645"
|
||||
if startNodeRPCServerResponse.Error != expectedError {
|
||||
t.Errorf("expected error not thrown: %s", expectedError)
|
||||
return false
|
||||
|
@ -265,7 +361,7 @@ func testCreateChildAccount(t *testing.T) bool {
|
|||
|
||||
// create an account
|
||||
createAccountResponse := geth.AccountInfo{}
|
||||
rawResponse := CreateAccount(C.CString(newAccountPassword))
|
||||
rawResponse := CreateAccount(C.CString(testConfig.Account1.Password))
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &createAccountResponse); err != nil {
|
||||
t.Errorf("cannot decode CreateAccount reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -286,7 +382,7 @@ func testCreateChildAccount(t *testing.T) bool {
|
|||
}
|
||||
|
||||
// obtain decrypted key, and make sure that extended key (which will be used as root for sub-accounts) is present
|
||||
account, key, err := keyStore.AccountDecryptedKey(account, newAccountPassword)
|
||||
account, key, err := keyStore.AccountDecryptedKey(account, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("can not obtain decrypted account key: %v", err)
|
||||
return false
|
||||
|
@ -299,7 +395,7 @@ func testCreateChildAccount(t *testing.T) bool {
|
|||
|
||||
// try creating sub-account, w/o selecting main account i.e. w/o login to main account
|
||||
createSubAccountResponse := geth.AccountInfo{}
|
||||
rawResponse = CreateChildAccount(C.CString(""), C.CString(newAccountPassword))
|
||||
rawResponse = CreateChildAccount(C.CString(""), C.CString(testConfig.Account1.Password))
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &createSubAccountResponse); err != nil {
|
||||
t.Errorf("cannot decode CreateChildAccount reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -311,7 +407,7 @@ func testCreateChildAccount(t *testing.T) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
err = geth.SelectAccount(address, newAccountPassword)
|
||||
err = geth.SelectAccount(address, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return false
|
||||
|
@ -333,7 +429,7 @@ func testCreateChildAccount(t *testing.T) bool {
|
|||
|
||||
// create sub-account (from implicit parent)
|
||||
createSubAccountResponse1 := geth.AccountInfo{}
|
||||
rawResponse = CreateChildAccount(C.CString(""), C.CString(newAccountPassword))
|
||||
rawResponse = CreateChildAccount(C.CString(""), C.CString(testConfig.Account1.Password))
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &createSubAccountResponse1); err != nil {
|
||||
t.Errorf("cannot decode CreateChildAccount reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -347,7 +443,7 @@ func testCreateChildAccount(t *testing.T) bool {
|
|||
|
||||
// make sure that sub-account index automatically progresses
|
||||
createSubAccountResponse2 := geth.AccountInfo{}
|
||||
rawResponse = CreateChildAccount(C.CString(""), C.CString(newAccountPassword))
|
||||
rawResponse = CreateChildAccount(C.CString(""), C.CString(testConfig.Account1.Password))
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &createSubAccountResponse2); err != nil {
|
||||
t.Errorf("cannot decode CreateChildAccount reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -365,7 +461,7 @@ func testCreateChildAccount(t *testing.T) bool {
|
|||
|
||||
// create sub-account (from explicit parent)
|
||||
createSubAccountResponse3 := geth.AccountInfo{}
|
||||
rawResponse = CreateChildAccount(C.CString(createSubAccountResponse2.Address), C.CString(newAccountPassword))
|
||||
rawResponse = CreateChildAccount(C.CString(createSubAccountResponse2.Address), C.CString(testConfig.Account1.Password))
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &createSubAccountResponse3); err != nil {
|
||||
t.Errorf("cannot decode CreateChildAccount reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -391,7 +487,7 @@ func testRecoverAccount(t *testing.T) bool {
|
|||
keyStore, _ := geth.NodeManagerInstance().AccountKeyStore()
|
||||
|
||||
// create an account
|
||||
address, pubKey, mnemonic, err := geth.CreateAccount(newAccountPassword)
|
||||
address, pubKey, mnemonic, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return false
|
||||
|
@ -400,7 +496,7 @@ func testRecoverAccount(t *testing.T) bool {
|
|||
|
||||
// try recovering using password + mnemonic
|
||||
recoverAccountResponse := geth.AccountInfo{}
|
||||
rawResponse := RecoverAccount(C.CString(newAccountPassword), C.CString(mnemonic))
|
||||
rawResponse := RecoverAccount(C.CString(testConfig.Account1.Password), C.CString(mnemonic))
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &recoverAccountResponse); err != nil {
|
||||
t.Errorf("cannot decode RecoverAccount reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -422,19 +518,19 @@ func testRecoverAccount(t *testing.T) bool {
|
|||
t.Errorf("can not get account from address: %v", err)
|
||||
}
|
||||
|
||||
account, key, err := keyStore.AccountDecryptedKey(account, newAccountPassword)
|
||||
account, key, err := keyStore.AccountDecryptedKey(account, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("can not obtain decrypted account key: %v", err)
|
||||
return false
|
||||
}
|
||||
extChild2String := key.ExtendedKey.String()
|
||||
|
||||
if err := keyStore.Delete(account, newAccountPassword); err != nil {
|
||||
if err := keyStore.Delete(account, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot remove account: %v", err)
|
||||
}
|
||||
|
||||
recoverAccountResponse = geth.AccountInfo{}
|
||||
rawResponse = RecoverAccount(C.CString(newAccountPassword), C.CString(mnemonic))
|
||||
rawResponse = RecoverAccount(C.CString(testConfig.Account1.Password), C.CString(mnemonic))
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &recoverAccountResponse); err != nil {
|
||||
t.Errorf("cannot decode RecoverAccount reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -451,7 +547,7 @@ func testRecoverAccount(t *testing.T) bool {
|
|||
}
|
||||
|
||||
// make sure that extended key exists and is imported ok too
|
||||
account, key, err = keyStore.AccountDecryptedKey(account, newAccountPassword)
|
||||
account, key, err = keyStore.AccountDecryptedKey(account, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("can not obtain decrypted account key: %v", err)
|
||||
return false
|
||||
|
@ -462,7 +558,7 @@ func testRecoverAccount(t *testing.T) bool {
|
|||
|
||||
// make sure that calling import several times, just returns from cache (no error is expected)
|
||||
recoverAccountResponse = geth.AccountInfo{}
|
||||
rawResponse = RecoverAccount(C.CString(newAccountPassword), C.CString(mnemonic))
|
||||
rawResponse = RecoverAccount(C.CString(testConfig.Account1.Password), C.CString(mnemonic))
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &recoverAccountResponse); err != nil {
|
||||
t.Errorf("cannot decode RecoverAccount reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -488,7 +584,7 @@ func testRecoverAccount(t *testing.T) bool {
|
|||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKeyCheck))) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
err = geth.SelectAccount(addressCheck, newAccountPassword)
|
||||
err = geth.SelectAccount(addressCheck, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return false
|
||||
|
@ -508,14 +604,14 @@ func testAccountSelect(t *testing.T) bool {
|
|||
}
|
||||
|
||||
// create an account
|
||||
address1, pubKey1, _, err := geth.CreateAccount(newAccountPassword)
|
||||
address1, pubKey1, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return false
|
||||
}
|
||||
t.Logf("Account created: {address: %s, key: %s}", address1, pubKey1)
|
||||
|
||||
address2, pubKey2, _, err := geth.CreateAccount(newAccountPassword)
|
||||
address2, pubKey2, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Error("Test failed: could not create account")
|
||||
return false
|
||||
|
@ -542,7 +638,7 @@ func testAccountSelect(t *testing.T) bool {
|
|||
}
|
||||
|
||||
loginResponse = geth.JSONError{}
|
||||
rawResponse = Login(C.CString(address1), C.CString(newAccountPassword))
|
||||
rawResponse = Login(C.CString(address1), C.CString(testConfig.Account1.Password))
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &loginResponse); err != nil {
|
||||
t.Errorf("cannot decode RecoverAccount reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -563,7 +659,7 @@ func testAccountSelect(t *testing.T) bool {
|
|||
}
|
||||
|
||||
loginResponse = geth.JSONError{}
|
||||
rawResponse = Login(C.CString(address2), C.CString(newAccountPassword))
|
||||
rawResponse = Login(C.CString(address2), C.CString(testConfig.Account1.Password))
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &loginResponse); err != nil {
|
||||
t.Errorf("cannot decode RecoverAccount reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -592,7 +688,7 @@ func testAccountLogout(t *testing.T) bool {
|
|||
}
|
||||
|
||||
// create an account
|
||||
address, pubKey, _, err := geth.CreateAccount(newAccountPassword)
|
||||
address, pubKey, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return false
|
||||
|
@ -605,7 +701,7 @@ func testAccountLogout(t *testing.T) bool {
|
|||
}
|
||||
|
||||
// select/login
|
||||
err = geth.SelectAccount(address, newAccountPassword)
|
||||
err = geth.SelectAccount(address, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return false
|
||||
|
@ -650,8 +746,8 @@ func testCompleteTransaction(t *testing.T) bool {
|
|||
backend.TransactionQueue().Reset()
|
||||
|
||||
// log into account from which transactions will be sent
|
||||
if err := geth.SelectAccount(testAddress, testAddressPassword); err != nil {
|
||||
t.Errorf("cannot select account: %v", testAddress)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -670,11 +766,10 @@ func testCompleteTransaction(t *testing.T) bool {
|
|||
}
|
||||
if envelope.Type == geth.EventTransactionQueued {
|
||||
event := envelope.Event.(map[string]interface{})
|
||||
t.Logf("transaction queued (will be completed in 5 secs): {id: %s}\n", event["id"].(string))
|
||||
time.Sleep(5 * time.Second)
|
||||
t.Logf("transaction queued (will be completed shortly): {id: %s}\n", event["id"].(string))
|
||||
|
||||
completeTxResponse := geth.CompleteTransactionResult{}
|
||||
rawResponse := CompleteTransaction(C.CString(event["id"].(string)), C.CString(testAddressPassword))
|
||||
rawResponse := CompleteTransaction(C.CString(event["id"].(string)), C.CString(testConfig.Account1.Password))
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &completeTxResponse); err != nil {
|
||||
t.Errorf("cannot decode RecoverAccount reponse (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -694,8 +789,8 @@ func testCompleteTransaction(t *testing.T) bool {
|
|||
|
||||
// this call blocks, up until Complete Transaction is called
|
||||
txHashCheck, err := backend.SendTransaction(nil, status.SendTxArgs{
|
||||
From: geth.FromAddress(testAddress),
|
||||
To: geth.ToAddress(testAddress1),
|
||||
From: geth.FromAddress(testConfig.Account1.Address),
|
||||
To: geth.ToAddress(testConfig.Account2.Address),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -735,8 +830,8 @@ func testCompleteMultipleQueuedTransactions(t *testing.T) bool {
|
|||
backend.TransactionQueue().Reset()
|
||||
|
||||
// log into account from which transactions will be sent
|
||||
if err := geth.SelectAccount(testAddress, testAddressPassword); err != nil {
|
||||
t.Errorf("cannot select account: %v", testAddress)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -765,8 +860,8 @@ func testCompleteMultipleQueuedTransactions(t *testing.T) bool {
|
|||
// this call blocks, and should return when DiscardQueuedTransaction() for a given tx id is called
|
||||
sendTx := func() {
|
||||
txHashCheck, err := backend.SendTransaction(nil, status.SendTxArgs{
|
||||
From: geth.FromAddress(testAddress),
|
||||
To: geth.ToAddress(testAddress1),
|
||||
From: geth.FromAddress(testConfig.Account1.Address),
|
||||
To: geth.ToAddress(testConfig.Account2.Address),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -789,7 +884,7 @@ func testCompleteMultipleQueuedTransactions(t *testing.T) bool {
|
|||
updatedTxIdStrings, _ := json.Marshal(parsedIds)
|
||||
|
||||
// complete
|
||||
resultsString := CompleteTransactions(C.CString(string(updatedTxIdStrings)), C.CString(testAddressPassword))
|
||||
resultsString := CompleteTransactions(C.CString(string(updatedTxIdStrings)), C.CString(testConfig.Account1.Password))
|
||||
resultsStruct := geth.CompleteTransactionsResult{}
|
||||
json.Unmarshal([]byte(C.GoString(resultsString)), &resultsStruct)
|
||||
results := resultsStruct.Results
|
||||
|
@ -870,8 +965,8 @@ func testDiscardTransaction(t *testing.T) bool {
|
|||
backend.TransactionQueue().Reset()
|
||||
|
||||
// log into account from which transactions will be sent
|
||||
if err := geth.SelectAccount(testAddress, testAddressPassword); err != nil {
|
||||
t.Errorf("cannot select account: %v", testAddress)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -912,7 +1007,7 @@ func testDiscardTransaction(t *testing.T) bool {
|
|||
}
|
||||
|
||||
// try completing discarded transaction
|
||||
_, err = geth.CompleteTransaction(txId, testAddressPassword)
|
||||
_, err = geth.CompleteTransaction(txId, testConfig.Account1.Password)
|
||||
if err.Error() != "transaction hash not found" {
|
||||
t.Error("expects tx not found, but call to CompleteTransaction succeeded")
|
||||
return
|
||||
|
@ -950,8 +1045,8 @@ func testDiscardTransaction(t *testing.T) bool {
|
|||
|
||||
// this call blocks, and should return when DiscardQueuedTransaction() is called
|
||||
txHashCheck, err := backend.SendTransaction(nil, status.SendTxArgs{
|
||||
From: geth.FromAddress(testAddress),
|
||||
To: geth.ToAddress(testAddress1),
|
||||
From: geth.FromAddress(testConfig.Account1.Address),
|
||||
To: geth.ToAddress(testConfig.Account2.Address),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
})
|
||||
if err != status.ErrQueuedTxDiscarded {
|
||||
|
@ -990,8 +1085,8 @@ func testDiscardMultipleQueuedTransactions(t *testing.T) bool {
|
|||
backend.TransactionQueue().Reset()
|
||||
|
||||
// log into account from which transactions will be sent
|
||||
if err := geth.SelectAccount(testAddress, testAddressPassword); err != nil {
|
||||
t.Errorf("cannot select account: %v", testAddress)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -1049,8 +1144,8 @@ func testDiscardMultipleQueuedTransactions(t *testing.T) bool {
|
|||
// this call blocks, and should return when DiscardQueuedTransaction() for a given tx id is called
|
||||
sendTx := func() {
|
||||
txHashCheck, err := backend.SendTransaction(nil, status.SendTxArgs{
|
||||
From: geth.FromAddress(testAddress),
|
||||
To: geth.ToAddress(testAddress1),
|
||||
From: geth.FromAddress(testConfig.Account1.Address),
|
||||
To: geth.ToAddress(testConfig.Account2.Address),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
})
|
||||
if err != status.ErrQueuedTxDiscarded {
|
||||
|
@ -1084,7 +1179,7 @@ func testDiscardMultipleQueuedTransactions(t *testing.T) bool {
|
|||
}
|
||||
|
||||
// try completing discarded transaction
|
||||
completeResultsString := CompleteTransactions(C.CString(string(updatedTxIdStrings)), C.CString(testAddressPassword))
|
||||
completeResultsString := CompleteTransactions(C.CString(string(updatedTxIdStrings)), C.CString(testConfig.Account1.Password))
|
||||
completeResultsStruct := geth.CompleteTransactionsResult{}
|
||||
json.Unmarshal([]byte(C.GoString(completeResultsString)), &completeResultsStruct)
|
||||
completeResults := completeResultsStruct.Results
|
||||
|
@ -1178,7 +1273,7 @@ func testJailFunctionCall(t *testing.T) bool {
|
|||
InitJail(C.CString(""))
|
||||
|
||||
// load Status JS and add test command to it
|
||||
statusJS := geth.LoadFromFile(testStatusJsFile) + `;
|
||||
statusJS := geth.LoadFromFile(filepath.Join(geth.RootDir, "geth/jail/testdata/status.js")) + `;
|
||||
_status_catalog.commands["testCommand"] = function (params) {
|
||||
return params.val * params.val;
|
||||
};`
|
||||
|
@ -1209,10 +1304,24 @@ func testJailFunctionCall(t *testing.T) bool {
|
|||
|
||||
func startTestNode(t *testing.T) <-chan struct{} {
|
||||
syncRequired := false
|
||||
if _, err := os.Stat(filepath.Join(testDataDir, "testnet")); os.IsNotExist(err) {
|
||||
if _, err := os.Stat(geth.TestDataDir); os.IsNotExist(err) {
|
||||
syncRequired = true
|
||||
}
|
||||
|
||||
// prepare node directory
|
||||
if err := os.MkdirAll(filepath.Join(geth.TestDataDir, "testnet", "keystore"), os.ModePerm); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
waitForNodeStart := make(chan struct{}, 1)
|
||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||
t.Log(jsonEvent)
|
||||
|
@ -1234,8 +1343,8 @@ func startTestNode(t *testing.T) <-chan struct{} {
|
|||
|
||||
// sync
|
||||
if syncRequired {
|
||||
t.Logf("Sync is required, it will take %d seconds", testNodeSyncSeconds)
|
||||
time.Sleep(testNodeSyncSeconds * time.Second) // LES syncs headers, so that we are up do date when it is done
|
||||
t.Logf("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)
|
||||
}
|
||||
|
@ -1246,12 +1355,18 @@ func startTestNode(t *testing.T) <-chan struct{} {
|
|||
})
|
||||
|
||||
go func() {
|
||||
response := StartNode(C.CString(testDataDir))
|
||||
configJSON := `{
|
||||
"NetworkId": ` + strconv.Itoa(params.TestNetworkId) + `,
|
||||
"DataDir": "` + geth.TestDataDir + `",
|
||||
"HTTPPort": ` + strconv.Itoa(testConfig.Node.HTTPPort) + `,
|
||||
"WSPort": ` + strconv.Itoa(testConfig.Node.WSPort) + `
|
||||
}`
|
||||
response := StartNode(C.CString(configJSON))
|
||||
err := geth.JSONError{}
|
||||
|
||||
json.Unmarshal([]byte(C.GoString(response)), &err)
|
||||
if err.Error != "" {
|
||||
t.Error("cannot start node")
|
||||
panic("cannot start node: " + err.Error)
|
||||
}
|
||||
}()
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"Node": {
|
||||
"SyncSeconds": 90,
|
||||
"HTTPPort": 8645,
|
||||
"WSPort": 8646
|
||||
},
|
||||
"Account1": {
|
||||
"Address": "0xadaf150b905cf5e6a778e553e15a139b6618bbb7",
|
||||
"Password": "asdfasdf"
|
||||
},
|
||||
"Account2": {
|
||||
"Address": "0xadd4d1d02e71c7360c53296968e59d57fd15e2ba",
|
||||
"Password": "asdfasdf"
|
||||
}
|
||||
}
|
|
@ -31,7 +31,7 @@ func TestAccountsList(t *testing.T) {
|
|||
}
|
||||
|
||||
// create an account
|
||||
address, _, _, err := geth.CreateAccount(newAccountPassword)
|
||||
address, _, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return
|
||||
|
@ -45,7 +45,7 @@ func TestAccountsList(t *testing.T) {
|
|||
}
|
||||
|
||||
// select account (sub-accounts will be created for this key)
|
||||
err = geth.SelectAccount(address, newAccountPassword)
|
||||
err = geth.SelectAccount(address, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
|
@ -63,7 +63,7 @@ func TestAccountsList(t *testing.T) {
|
|||
}
|
||||
|
||||
// create sub-account 1
|
||||
subAccount1, subPubKey1, err := geth.CreateChildAccount("", newAccountPassword)
|
||||
subAccount1, subPubKey1, err := geth.CreateChildAccount("", testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("cannot create sub-account: %v", err)
|
||||
return
|
||||
|
@ -86,7 +86,7 @@ func TestAccountsList(t *testing.T) {
|
|||
}
|
||||
|
||||
// create sub-account 2, index automatically progresses
|
||||
subAccount2, subPubKey2, err := geth.CreateChildAccount("", newAccountPassword)
|
||||
subAccount2, subPubKey2, err := geth.CreateChildAccount("", testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("cannot create sub-account: %v", err)
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ func TestAccountsList(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCreateChildAccount(t *testing.T) {
|
||||
func TestAccountsCreateChildAccount(t *testing.T) {
|
||||
err := geth.PrepareTestNode()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -136,7 +136,7 @@ func TestCreateChildAccount(t *testing.T) {
|
|||
}
|
||||
|
||||
// create an account
|
||||
address, pubKey, mnemonic, err := geth.CreateAccount(newAccountPassword)
|
||||
address, pubKey, mnemonic, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return
|
||||
|
@ -150,7 +150,7 @@ func TestCreateChildAccount(t *testing.T) {
|
|||
}
|
||||
|
||||
// obtain decrypted key, and make sure that extended key (which will be used as root for sub-accounts) is present
|
||||
account, key, err := keyStore.AccountDecryptedKey(account, newAccountPassword)
|
||||
account, key, err := keyStore.AccountDecryptedKey(account, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("can not obtain decrypted account key: %v", err)
|
||||
return
|
||||
|
@ -162,13 +162,13 @@ func TestCreateChildAccount(t *testing.T) {
|
|||
}
|
||||
|
||||
// try creating sub-account, w/o selecting main account i.e. w/o login to main account
|
||||
_, _, err = geth.CreateChildAccount("", newAccountPassword)
|
||||
_, _, err = geth.CreateChildAccount("", testConfig.Account1.Password)
|
||||
if !reflect.DeepEqual(err, geth.ErrNoAccountSelected) {
|
||||
t.Errorf("expected error is not returned (tried to create sub-account w/o login): %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = geth.SelectAccount(address, newAccountPassword)
|
||||
err = geth.SelectAccount(address, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
|
@ -182,14 +182,14 @@ func TestCreateChildAccount(t *testing.T) {
|
|||
}
|
||||
|
||||
// create sub-account (from implicit parent)
|
||||
subAccount1, subPubKey1, err := geth.CreateChildAccount("", newAccountPassword)
|
||||
subAccount1, subPubKey1, err := geth.CreateChildAccount("", testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("cannot create sub-account: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// make sure that sub-account index automatically progresses
|
||||
subAccount2, subPubKey2, err := geth.CreateChildAccount("", newAccountPassword)
|
||||
subAccount2, subPubKey2, err := geth.CreateChildAccount("", testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("cannot create sub-account: %v", err)
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ func TestCreateChildAccount(t *testing.T) {
|
|||
}
|
||||
|
||||
// create sub-account (from explicit parent)
|
||||
subAccount3, subPubKey3, err := geth.CreateChildAccount(subAccount2, newAccountPassword)
|
||||
subAccount3, subPubKey3, err := geth.CreateChildAccount(subAccount2, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("cannot create sub-account: %v", err)
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ func TestCreateChildAccount(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestRecoverAccount(t *testing.T) {
|
||||
func TestAccountsRecoverAccount(t *testing.T) {
|
||||
err := geth.PrepareTestNode()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -219,7 +219,7 @@ func TestRecoverAccount(t *testing.T) {
|
|||
keyStore, _ := geth.NodeManagerInstance().AccountKeyStore()
|
||||
|
||||
// create an account
|
||||
address, pubKey, mnemonic, err := geth.CreateAccount(newAccountPassword)
|
||||
address, pubKey, mnemonic, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return
|
||||
|
@ -227,7 +227,7 @@ func TestRecoverAccount(t *testing.T) {
|
|||
t.Logf("Account created: {address: %s, key: %s, mnemonic:%s}", address, pubKey, mnemonic)
|
||||
|
||||
// try recovering using password + mnemonic
|
||||
addressCheck, pubKeyCheck, err := geth.RecoverAccount(newAccountPassword, mnemonic)
|
||||
addressCheck, pubKeyCheck, err := geth.RecoverAccount(testConfig.Account1.Password, mnemonic)
|
||||
if err != nil {
|
||||
t.Errorf("recover account failed: %v", err)
|
||||
return
|
||||
|
@ -242,18 +242,18 @@ func TestRecoverAccount(t *testing.T) {
|
|||
t.Errorf("can not get account from address: %v", err)
|
||||
}
|
||||
|
||||
account, key, err := keyStore.AccountDecryptedKey(account, newAccountPassword)
|
||||
account, key, err := keyStore.AccountDecryptedKey(account, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("can not obtain decrypted account key: %v", err)
|
||||
return
|
||||
}
|
||||
extChild2String := key.ExtendedKey.String()
|
||||
|
||||
if err := keyStore.Delete(account, newAccountPassword); err != nil {
|
||||
if err := keyStore.Delete(account, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot remove account: %v", err)
|
||||
}
|
||||
|
||||
addressCheck, pubKeyCheck, err = geth.RecoverAccount(newAccountPassword, mnemonic)
|
||||
addressCheck, pubKeyCheck, err = geth.RecoverAccount(testConfig.Account1.Password, mnemonic)
|
||||
if err != nil {
|
||||
t.Errorf("recover account failed (for non-cached account): %v", err)
|
||||
return
|
||||
|
@ -263,7 +263,7 @@ func TestRecoverAccount(t *testing.T) {
|
|||
}
|
||||
|
||||
// make sure that extended key exists and is imported ok too
|
||||
account, key, err = keyStore.AccountDecryptedKey(account, newAccountPassword)
|
||||
account, key, err = keyStore.AccountDecryptedKey(account, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("can not obtain decrypted account key: %v", err)
|
||||
return
|
||||
|
@ -273,7 +273,7 @@ func TestRecoverAccount(t *testing.T) {
|
|||
}
|
||||
|
||||
// make sure that calling import several times, just returns from cache (no error is expected)
|
||||
addressCheck, pubKeyCheck, err = geth.RecoverAccount(newAccountPassword, mnemonic)
|
||||
addressCheck, pubKeyCheck, err = geth.RecoverAccount(testConfig.Account1.Password, mnemonic)
|
||||
if err != nil {
|
||||
t.Errorf("recover account failed (for non-cached account): %v", err)
|
||||
return
|
||||
|
@ -292,7 +292,7 @@ func TestRecoverAccount(t *testing.T) {
|
|||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKeyCheck))) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
err = geth.SelectAccount(addressCheck, newAccountPassword)
|
||||
err = geth.SelectAccount(addressCheck, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
|
@ -317,14 +317,14 @@ func TestAccountSelect(t *testing.T) {
|
|||
}
|
||||
|
||||
// create an account
|
||||
address1, pubKey1, _, err := geth.CreateAccount(newAccountPassword)
|
||||
address1, pubKey1, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return
|
||||
}
|
||||
t.Logf("Account created: {address: %s, key: %s}", address1, pubKey1)
|
||||
|
||||
address2, pubKey2, _, err := geth.CreateAccount(newAccountPassword)
|
||||
address2, pubKey2, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Error("Test failed: could not create account")
|
||||
return
|
||||
|
@ -342,7 +342,7 @@ func TestAccountSelect(t *testing.T) {
|
|||
t.Error("select account is expected to throw error: wrong password used")
|
||||
return
|
||||
}
|
||||
err = geth.SelectAccount(address1, newAccountPassword)
|
||||
err = geth.SelectAccount(address1, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
|
@ -355,7 +355,7 @@ func TestAccountSelect(t *testing.T) {
|
|||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey2))) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
err = geth.SelectAccount(address2, newAccountPassword)
|
||||
err = geth.SelectAccount(address2, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
|
@ -368,7 +368,7 @@ func TestAccountSelect(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAccountLogout(t *testing.T) {
|
||||
func TestAccountsLogout(t *testing.T) {
|
||||
|
||||
err := geth.PrepareTestNode()
|
||||
if err != nil {
|
||||
|
@ -382,7 +382,7 @@ func TestAccountLogout(t *testing.T) {
|
|||
}
|
||||
|
||||
// create an account
|
||||
address, pubKey, _, err := geth.CreateAccount(newAccountPassword)
|
||||
address, pubKey, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return
|
||||
|
@ -394,7 +394,7 @@ func TestAccountLogout(t *testing.T) {
|
|||
}
|
||||
|
||||
// select/login
|
||||
err = geth.SelectAccount(address, newAccountPassword)
|
||||
err = geth.SelectAccount(address, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
|
@ -414,7 +414,7 @@ func TestAccountLogout(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestSelectedAccountOnNodeRestart(t *testing.T) {
|
||||
func TestAccountsSelectedAccountOnNodeRestart(t *testing.T) {
|
||||
err := geth.PrepareTestNode()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -428,13 +428,13 @@ func TestSelectedAccountOnNodeRestart(t *testing.T) {
|
|||
}
|
||||
|
||||
// create test accounts
|
||||
address1, pubKey1, _, err := geth.CreateAccount(newAccountPassword)
|
||||
address1, pubKey1, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return
|
||||
}
|
||||
t.Logf("account1 created: {address: %s, key: %s}", address1, pubKey1)
|
||||
address2, pubKey2, _, err := geth.CreateAccount(newAccountPassword)
|
||||
address2, pubKey2, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return
|
||||
|
@ -458,7 +458,7 @@ func TestSelectedAccountOnNodeRestart(t *testing.T) {
|
|||
t.Error("select account is expected to throw error: wrong password used")
|
||||
return
|
||||
}
|
||||
err = geth.SelectAccount(address1, newAccountPassword)
|
||||
err = geth.SelectAccount(address1, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not select account: %v", err)
|
||||
return
|
||||
|
@ -471,7 +471,7 @@ func TestSelectedAccountOnNodeRestart(t *testing.T) {
|
|||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey2))) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
err = geth.SelectAccount(address2, newAccountPassword)
|
||||
err = geth.SelectAccount(address2, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
|
@ -528,7 +528,7 @@ func TestSelectedAccountOnNodeRestart(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNodeRestartWithNoSelectedAccount(t *testing.T) {
|
||||
func TestAccountsNodeRestartWithNoSelectedAccount(t *testing.T) {
|
||||
err := geth.PrepareTestNode()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
@ -544,7 +544,7 @@ func TestNodeRestartWithNoSelectedAccount(t *testing.T) {
|
|||
}
|
||||
|
||||
// create test accounts
|
||||
address1, pubKey1, _, err := geth.CreateAccount(newAccountPassword)
|
||||
address1, pubKey1, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return
|
||||
|
|
|
@ -2,6 +2,7 @@ package jail_test
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -10,21 +11,37 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/status-im/status-go/geth"
|
||||
"github.com/status-im/status-go/jail"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
"github.com/status-im/status-go/geth/jail"
|
||||
)
|
||||
|
||||
const (
|
||||
TEST_ADDRESS = "0xadaf150b905cf5e6a778e553e15a139b6618bbb7"
|
||||
TEST_ADDRESS_PASSWORD = "asdfasdf"
|
||||
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"
|
||||
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/"
|
||||
)
|
||||
|
||||
var testConfig *geth.TestConfig
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// load shared test configuration
|
||||
var err error
|
||||
testConfig, err = geth.LoadTestConfig()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// run tests
|
||||
retCode := m.Run()
|
||||
|
||||
//time.Sleep(25 * time.Second) // to give some time to propagate txs to the rest of the network
|
||||
os.Exit(retCode)
|
||||
}
|
||||
|
||||
func TestJailUnInited(t *testing.T) {
|
||||
errorWrapper := func(err error) string {
|
||||
return `{"error":"` + err.Error() + `"}`
|
||||
|
@ -174,7 +191,7 @@ func TestJailRPCSend(t *testing.T) {
|
|||
// internally (since we replaced `web3.send` with `jail.Send`)
|
||||
// all requests to web3 are forwarded to `jail.Send`
|
||||
_, err = vm.Run(`
|
||||
var balance = web3.eth.getBalance("` + TEST_ADDRESS + `");
|
||||
var balance = web3.eth.getBalance("` + testConfig.Account1.Address + `");
|
||||
var sendResult = web3.fromWei(balance, "ether")
|
||||
`)
|
||||
if err != nil {
|
||||
|
@ -199,7 +216,7 @@ func TestJailRPCSend(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
t.Logf("Balance of %.2f ETH found on '%s' account", balance, TEST_ADDRESS)
|
||||
t.Logf("Balance of %.2f ETH found on '%s' account", balance, testConfig.Account1.Address)
|
||||
}
|
||||
|
||||
func TestJailSendQueuedTransaction(t *testing.T) {
|
||||
|
@ -210,13 +227,13 @@ func TestJailSendQueuedTransaction(t *testing.T) {
|
|||
}
|
||||
|
||||
// log into account from which transactions will be sent
|
||||
if err := geth.SelectAccount(TEST_ADDRESS, TEST_ADDRESS_PASSWORD); err != nil {
|
||||
t.Errorf("cannot select account: %v", TEST_ADDRESS)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return
|
||||
}
|
||||
|
||||
txParams := `{
|
||||
"from": "` + TEST_ADDRESS + `",
|
||||
"from": "` + testConfig.Account1.Address + `",
|
||||
"to": "0xf82da7547534045b4e00442bc89e16186cf8c272",
|
||||
"value": "0.000001"
|
||||
}`
|
||||
|
@ -251,11 +268,10 @@ func TestJailSendQueuedTransaction(t *testing.T) {
|
|||
return
|
||||
}
|
||||
}
|
||||
t.Logf("Transaction queued (will be completed in 5 secs): {id: %s}\n", event["id"].(string))
|
||||
time.Sleep(5 * time.Second)
|
||||
t.Logf("Transaction queued (will be completed shortly): {id: %s}\n", event["id"].(string))
|
||||
|
||||
var txHash common.Hash
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), TEST_ADDRESS_PASSWORD); err != nil {
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot complete queued transation[%v]: %v", event["id"], err)
|
||||
} else {
|
||||
t.Logf("Transaction complete: https://testnet.etherscan.io/tx/%s", txHash.Hex())
|
||||
|
@ -293,7 +309,7 @@ func TestJailSendQueuedTransaction(t *testing.T) {
|
|||
},
|
||||
{
|
||||
`["commands", "getBalance"]`,
|
||||
`{"address": "` + TEST_ADDRESS + `"}`,
|
||||
`{"address": "` + testConfig.Account1.Address + `"}`,
|
||||
`{"result": {"balance":42}}`,
|
||||
},
|
||||
},
|
||||
|
@ -311,7 +327,7 @@ func TestJailSendQueuedTransaction(t *testing.T) {
|
|||
},
|
||||
{
|
||||
`["commands", "getBalance"]`,
|
||||
`{"address": "` + TEST_ADDRESS + `"}`,
|
||||
`{"address": "` + testConfig.Account1.Address + `"}`,
|
||||
`{"result": {"context":{},"result":{"balance":42}}}`, // note emtpy (but present) context!
|
||||
},
|
||||
},
|
||||
|
@ -329,7 +345,7 @@ func TestJailSendQueuedTransaction(t *testing.T) {
|
|||
},
|
||||
{
|
||||
`["commands", "getBalance"]`,
|
||||
`{"address": "` + TEST_ADDRESS + `"}`,
|
||||
`{"address": "` + testConfig.Account1.Address + `"}`,
|
||||
`{"result": {"balance":42}}`, // note emtpy context!
|
||||
},
|
||||
},
|
||||
|
@ -347,7 +363,7 @@ func TestJailSendQueuedTransaction(t *testing.T) {
|
|||
},
|
||||
{
|
||||
`["commands", "getBalance"]`,
|
||||
`{"address": "` + TEST_ADDRESS + `"}`,
|
||||
`{"address": "` + testConfig.Account1.Address + `"}`,
|
||||
`{"result": {"context":{"message_id":"42"},"result":{"balance":42}}}`, // message id in context, but default one is used!
|
||||
},
|
||||
},
|
||||
|
@ -596,15 +612,14 @@ func TestContractDeployment(t *testing.T) {
|
|||
if envelope.Type == geth.EventTransactionQueued {
|
||||
event := envelope.Event.(map[string]interface{})
|
||||
|
||||
t.Logf("Transaction queued (will be completed in 5 secs): {id: %s}\n", event["id"].(string))
|
||||
time.Sleep(5 * time.Second)
|
||||
t.Logf("Transaction queued (will be completed shortly): {id: %s}\n", event["id"].(string))
|
||||
|
||||
if err := geth.SelectAccount(TEST_ADDRESS, TEST_ADDRESS_PASSWORD); err != nil {
|
||||
t.Errorf("cannot select account: %v", TEST_ADDRESS)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return
|
||||
}
|
||||
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), TEST_ADDRESS_PASSWORD); err != nil {
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot complete queued transation[%v]: %v", event["id"], err)
|
||||
return
|
||||
} else {
|
||||
|
@ -620,9 +635,9 @@ func TestContractDeployment(t *testing.T) {
|
|||
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: '` + TEST_ADDRESS + `',
|
||||
from: '` + testConfig.Account1.Address + `',
|
||||
data: '0x6060604052341561000c57fe5b5b60a58061001b6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636ffa1caa14603a575bfe5b3415604157fe5b60556004808035906020019091905050606b565b6040518082815260200191505060405180910390f35b60008160020290505b9190505600a165627a7a72305820ccdadd737e4ac7039963b54cee5e5afb25fa859a275252bdcf06f653155228210029',
|
||||
gas: '` + strconv.Itoa(geth.DefaultGas) + `'
|
||||
gas: '` + strconv.Itoa(params.DefaultGas) + `'
|
||||
}, function (e, contract){
|
||||
if (!e) {
|
||||
responseValue = contract.transactionHash
|
||||
|
@ -689,12 +704,12 @@ func TestGasEstimation(t *testing.T) {
|
|||
|
||||
t.Logf("Transaction queued (will be completed immediately): {id: %s}\n", event["id"].(string))
|
||||
|
||||
if err := geth.SelectAccount(TEST_ADDRESS, TEST_ADDRESS_PASSWORD); err != nil {
|
||||
t.Errorf("cannot select account: %v", TEST_ADDRESS)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return
|
||||
}
|
||||
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), TEST_ADDRESS_PASSWORD); err != nil {
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot complete queued transation[%v]: %v", event["id"], err)
|
||||
return
|
||||
} else {
|
||||
|
@ -710,7 +725,7 @@ func TestGasEstimation(t *testing.T) {
|
|||
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: '` + TEST_ADDRESS + `',
|
||||
from: '` + testConfig.Account1.Address + `',
|
||||
data: '0x6060604052341561000c57fe5b5b60a58061001b6000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680636ffa1caa14603a575bfe5b3415604157fe5b60556004808035906020019091905050606b565b6040518082815260200191505060405180910390f35b60008160020290505b9190505600a165627a7a72305820ccdadd737e4ac7039963b54cee5e5afb25fa859a275252bdcf06f653155228210029',
|
||||
}, function (e, contract){
|
||||
if (!e) {
|
||||
|
@ -741,5 +756,5 @@ func TestGasEstimation(t *testing.T) {
|
|||
if !reflect.DeepEqual(response, expectedResponse) {
|
||||
t.Errorf("expected response is not returned: expected %s, got %s", expectedResponse, response)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
205
geth/node.go
205
geth/node.go
|
@ -4,10 +4,8 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
|
@ -15,60 +13,23 @@ import (
|
|||
"syscall"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/les"
|
||||
"github.com/ethereum/go-ethereum/logger"
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
gethparams "github.com/ethereum/go-ethereum/params"
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv2"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
const (
|
||||
ClientIdentifier = "StatusIM" // Client identifier to advertise over the network
|
||||
IPCFile = "geth.ipc" // Filename of exposed IPC-RPC Server
|
||||
HTTPPort = 8545 // HTTP-RPC port (replaced in unit tests)
|
||||
WSPort = 8546 // WS-RPC port (replaced in unit tests)
|
||||
MaxPeers = 25
|
||||
MaxLightPeers = 20
|
||||
MaxPendingPeers = 0
|
||||
DefaultGas = 180000
|
||||
|
||||
ProcessFileDescriptorLimit = uint64(2048)
|
||||
DatabaseCacheSize = 128 // Megabytes of memory allocated to internal caching (min 16MB / database forced)
|
||||
|
||||
EventNodeStarted = "node.started"
|
||||
EventNodeCrashed = "node.crashed"
|
||||
)
|
||||
|
||||
// Gas price settings
|
||||
var (
|
||||
GasPrice = new(big.Int).Mul(big.NewInt(20), common.Shannon) // Minimal gas price to accept for mining a transactions
|
||||
GpoMinGasPrice = new(big.Int).Mul(big.NewInt(20), common.Shannon) // Minimum suggested gas price
|
||||
GpoMaxGasPrice = new(big.Int).Mul(big.NewInt(500), common.Shannon) // Maximum suggested gas price
|
||||
GpoFullBlockRatio = 80 // Full block threshold for gas price calculation (%)
|
||||
GpobaseStepDown = 10 // Suggested gas price base step down ratio (1/1000)
|
||||
GpobaseStepUp = 100 // Suggested gas price base step up ratio (1/1000)
|
||||
GpobaseCorrectionFactor = 110 // Suggested gas price base correction factor (%)
|
||||
)
|
||||
|
||||
// default node configuration options
|
||||
var (
|
||||
UseTestnetFlag = "true" // to be overridden via -ldflags '-X geth.UseTestnetFlag'
|
||||
UseTestnet = false
|
||||
)
|
||||
|
||||
func init() {
|
||||
if UseTestnetFlag == "true" { // set at compile time, here we make sure to set corresponding boolean flag
|
||||
UseTestnet = true
|
||||
}
|
||||
}
|
||||
|
||||
// node-related errors
|
||||
var (
|
||||
ErrEthServiceRegistrationFailure = errors.New("failed to register the Ethereum service")
|
||||
|
@ -76,22 +37,12 @@ var (
|
|||
ErrLightEthRegistrationFailure = errors.New("failed to register the LES service")
|
||||
)
|
||||
|
||||
// NodeConfig stores configuration options for a node
|
||||
type NodeConfig struct {
|
||||
DataDir string // base data directory
|
||||
IPCEnabled bool // whether IPC-RPC Server is enabled or not
|
||||
HTTPPort int // HTTP-RPC Server port
|
||||
WSPort int // WS-RPC Server port
|
||||
WSEnabled bool // whether WS-RPC Server is enabled or not
|
||||
TLSEnabled bool // whether TLS support should be enabled on node or not
|
||||
}
|
||||
|
||||
// Node represents running node (serves as a wrapper around P2P node)
|
||||
type Node struct {
|
||||
config *NodeConfig // configuration used to create Status node
|
||||
geth *node.Node // reference to the running Geth node
|
||||
gethConfig *node.Config // configuration used to create P2P node
|
||||
started chan struct{} // channel to wait for node to start
|
||||
config *params.NodeConfig // configuration used to create Status node
|
||||
geth *node.Node // reference to the running Geth node
|
||||
gethConfig *node.Config // configuration used to create P2P node
|
||||
started chan struct{} // channel to wait for node to start
|
||||
}
|
||||
|
||||
// Inited checks whether status node has been properly initialized
|
||||
|
@ -105,24 +56,16 @@ func (n *Node) GethStack() *node.Node {
|
|||
}
|
||||
|
||||
// MakeNode create a geth node entity
|
||||
func MakeNode(config *NodeConfig) *Node {
|
||||
func MakeNode(config *params.NodeConfig) *Node {
|
||||
glog.CopyStandardLogTo("INFO")
|
||||
glog.SetToStderr(true)
|
||||
|
||||
dataDir := config.DataDir
|
||||
if UseTestnet {
|
||||
dataDir = filepath.Join(config.DataDir, "testnet")
|
||||
}
|
||||
|
||||
// exposed RPC APIs
|
||||
exposedAPIs := "db,eth,net,web3,shh,personal,admin" // TODO remove "admin" on main net
|
||||
|
||||
// configure required node (should you need to update node's config, e.g. add bootstrap nodes, see node.Config)
|
||||
stackConfig := &node.Config{
|
||||
DataDir: dataDir,
|
||||
DataDir: config.DataDir,
|
||||
UseLightweightKDF: true,
|
||||
Name: ClientIdentifier,
|
||||
Version: params.Version,
|
||||
Name: config.Name,
|
||||
Version: config.Version,
|
||||
NoDiscovery: true,
|
||||
DiscoveryV5: false,
|
||||
DiscoveryV5Addr: ":0",
|
||||
|
@ -130,17 +73,17 @@ func MakeNode(config *NodeConfig) *Node {
|
|||
BootstrapNodesV5: makeBootstrapNodesV5(),
|
||||
ListenAddr: ":0",
|
||||
NAT: nat.Any(),
|
||||
MaxPeers: MaxPeers,
|
||||
MaxPendingPeers: MaxPendingPeers,
|
||||
IPCPath: makeIPCPath(dataDir, config.IPCEnabled),
|
||||
HTTPHost: node.DefaultHTTPHost,
|
||||
MaxPeers: config.MaxPeers,
|
||||
MaxPendingPeers: config.MaxPendingPeers,
|
||||
IPCPath: makeIPCPath(config),
|
||||
HTTPHost: config.HTTPHost,
|
||||
HTTPPort: config.HTTPPort,
|
||||
HTTPCors: "*",
|
||||
HTTPModules: strings.Split(exposedAPIs, ","),
|
||||
WSHost: makeWSHost(config.WSEnabled),
|
||||
HTTPModules: strings.Split(config.APIModules, ","),
|
||||
WSHost: makeWSHost(config),
|
||||
WSPort: config.WSPort,
|
||||
WSOrigins: "*",
|
||||
WSModules: strings.Split(exposedAPIs, ","),
|
||||
WSModules: strings.Split(config.APIModules, ","),
|
||||
}
|
||||
|
||||
stack, err := node.New(stackConfig)
|
||||
|
@ -149,12 +92,12 @@ func MakeNode(config *NodeConfig) *Node {
|
|||
}
|
||||
|
||||
// start Ethereum service
|
||||
if err := activateEthService(stack, makeDefaultExtra()); err != nil {
|
||||
if err := activateEthService(stack, config); err != nil {
|
||||
Fatalf(fmt.Errorf("%v: %v", ErrEthServiceRegistrationFailure, err))
|
||||
}
|
||||
|
||||
// start Whisper service
|
||||
if err := activateShhService(stack); err != nil {
|
||||
if err := activateShhService(stack, config); err != nil {
|
||||
Fatalf(fmt.Errorf("%v: %v", ErrSshServiceRegistrationFailure, err))
|
||||
}
|
||||
|
||||
|
@ -167,35 +110,29 @@ func MakeNode(config *NodeConfig) *Node {
|
|||
}
|
||||
|
||||
// activateEthService configures and registers the eth.Ethereum service with a given node.
|
||||
func activateEthService(stack *node.Node, extra []byte) error {
|
||||
func activateEthService(stack *node.Node, config *params.NodeConfig) error {
|
||||
ethConf := ð.Config{
|
||||
Etherbase: common.Address{},
|
||||
ChainConfig: makeChainConfig(stack),
|
||||
ChainConfig: makeChainConfig(config),
|
||||
FastSync: false,
|
||||
LightMode: true,
|
||||
LightServ: 60,
|
||||
LightPeers: MaxLightPeers,
|
||||
MaxPeers: MaxPeers,
|
||||
DatabaseCache: DatabaseCacheSize,
|
||||
MaxPeers: config.MaxPeers,
|
||||
DatabaseCache: config.LightEthConfig.DatabaseCache,
|
||||
DatabaseHandles: makeDatabaseHandles(),
|
||||
NetworkId: 1, // Olympic
|
||||
NetworkId: config.NetworkId,
|
||||
Genesis: config.LightEthConfig.Genesis,
|
||||
MinerThreads: runtime.NumCPU(),
|
||||
GasPrice: GasPrice,
|
||||
GpoMinGasPrice: GpoMinGasPrice,
|
||||
GpoMaxGasPrice: GpoMaxGasPrice,
|
||||
GpoFullBlockRatio: GpoFullBlockRatio,
|
||||
GpobaseStepDown: GpobaseStepDown,
|
||||
GpobaseStepUp: GpobaseStepUp,
|
||||
GpobaseCorrectionFactor: GpobaseCorrectionFactor,
|
||||
GasPrice: params.GasPrice,
|
||||
GpoMinGasPrice: params.GpoMinGasPrice,
|
||||
GpoMaxGasPrice: params.GpoMaxGasPrice,
|
||||
GpoFullBlockRatio: params.GpoFullBlockRatio,
|
||||
GpobaseStepDown: params.GpobaseStepDown,
|
||||
GpobaseStepUp: params.GpobaseStepUp,
|
||||
GpobaseCorrectionFactor: params.GpobaseCorrectionFactor,
|
||||
SolcPath: "solc",
|
||||
AutoDAG: false,
|
||||
}
|
||||
|
||||
if UseTestnet {
|
||||
ethConf.NetworkId = 3
|
||||
ethConf.Genesis = core.DefaultTestnetGenesisBlock()
|
||||
}
|
||||
|
||||
if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
||||
return les.New(ctx, ethConf)
|
||||
}); err != nil {
|
||||
|
@ -206,7 +143,7 @@ func activateEthService(stack *node.Node, extra []byte) error {
|
|||
}
|
||||
|
||||
// activateShhService configures Whisper and adds it to the given node.
|
||||
func activateShhService(stack *node.Node) error {
|
||||
func activateShhService(stack *node.Node, config *params.NodeConfig) error {
|
||||
serviceConstructor := func(*node.ServiceContext) (node.Service, error) {
|
||||
return whisper.New(), nil
|
||||
}
|
||||
|
@ -218,47 +155,44 @@ func activateShhService(stack *node.Node) error {
|
|||
}
|
||||
|
||||
// makeIPCPath returns IPC-RPC filename
|
||||
func makeIPCPath(dataDir string, ipcEnabled bool) string {
|
||||
if !ipcEnabled {
|
||||
func makeIPCPath(config *params.NodeConfig) string {
|
||||
if !config.IPCEnabled {
|
||||
return ""
|
||||
}
|
||||
|
||||
return path.Join(dataDir, IPCFile)
|
||||
return path.Join(config.DataDir, config.IPCFile)
|
||||
}
|
||||
|
||||
// makeWSHost returns WS-RPC Server host, given enabled/disabled flag
|
||||
func makeWSHost(wsEnabled bool) string {
|
||||
if !wsEnabled {
|
||||
func makeWSHost(config *params.NodeConfig) string {
|
||||
if !config.WSEnabled {
|
||||
return ""
|
||||
}
|
||||
|
||||
return node.DefaultWSHost
|
||||
return config.WSHost
|
||||
}
|
||||
|
||||
// makeChainConfig reads the chain configuration from the database in the datadir.
|
||||
func makeChainConfig(stack *node.Node) *params.ChainConfig {
|
||||
config := new(params.ChainConfig)
|
||||
func makeChainConfig(config *params.NodeConfig) *gethparams.ChainConfig {
|
||||
chainConfig := new(gethparams.ChainConfig)
|
||||
|
||||
if UseTestnet {
|
||||
config = params.TestnetChainConfig
|
||||
} else {
|
||||
// Homestead fork
|
||||
config.HomesteadBlock = params.MainNetHomesteadBlock
|
||||
// DAO fork
|
||||
config.DAOForkBlock = params.MainNetDAOForkBlock
|
||||
config.DAOForkSupport = true
|
||||
// Homestead fork
|
||||
chainConfig.HomesteadBlock = config.HomesteadBlock
|
||||
|
||||
// DoS reprice fork
|
||||
config.EIP150Block = params.MainNetHomesteadGasRepriceBlock
|
||||
config.EIP150Hash = params.MainNetHomesteadGasRepriceHash
|
||||
// DAO fork
|
||||
chainConfig.DAOForkBlock = config.DAOForkBlock
|
||||
chainConfig.DAOForkSupport = config.DAOForkSupport
|
||||
|
||||
// DoS state cleanup fork
|
||||
config.EIP155Block = params.MainNetSpuriousDragon
|
||||
config.EIP158Block = params.MainNetSpuriousDragon
|
||||
config.ChainId = params.MainNetChainID
|
||||
}
|
||||
// DoS reprice fork
|
||||
chainConfig.EIP150Block = config.EIP150Block
|
||||
chainConfig.EIP150Hash = config.EIP150Hash
|
||||
|
||||
return config
|
||||
// DoS state cleanup fork
|
||||
chainConfig.EIP155Block = config.EIP155Block
|
||||
chainConfig.EIP158Block = config.EIP158Block
|
||||
chainConfig.ChainId = config.ChainId
|
||||
|
||||
return chainConfig
|
||||
}
|
||||
|
||||
// makeDatabaseHandles makes sure that enough file descriptors are available to the process
|
||||
|
@ -272,8 +206,8 @@ func makeDatabaseHandles() int {
|
|||
|
||||
// increase limit
|
||||
limit.Cur = limit.Max
|
||||
if limit.Cur > ProcessFileDescriptorLimit {
|
||||
limit.Cur = ProcessFileDescriptorLimit
|
||||
if limit.Cur > params.DefaultFileDescriptorLimit {
|
||||
limit.Cur = params.DefaultFileDescriptorLimit
|
||||
}
|
||||
if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
|
||||
Fatalf(err)
|
||||
|
@ -285,34 +219,13 @@ func makeDatabaseHandles() int {
|
|||
}
|
||||
|
||||
// cap limit
|
||||
if limit.Cur > ProcessFileDescriptorLimit {
|
||||
limit.Cur = ProcessFileDescriptorLimit
|
||||
if limit.Cur > params.DefaultFileDescriptorLimit {
|
||||
limit.Cur = params.DefaultFileDescriptorLimit
|
||||
}
|
||||
|
||||
return int(limit.Cur) / 2
|
||||
}
|
||||
|
||||
func makeDefaultExtra() []byte {
|
||||
var clientInfo = struct {
|
||||
Version uint
|
||||
Name string
|
||||
GoVersion string
|
||||
Os string
|
||||
}{uint(params.VersionMajor<<16 | params.VersionMinor<<8 | params.VersionPatch), ClientIdentifier, runtime.Version(), runtime.GOOS}
|
||||
extra, err := rlp.EncodeToBytes(clientInfo)
|
||||
if err != nil {
|
||||
glog.V(logger.Warn).Infoln("error setting canonical miner information:", err)
|
||||
}
|
||||
|
||||
if uint64(len(extra)) > params.MaximumExtraDataSize.Uint64() {
|
||||
glog.V(logger.Warn).Infoln("error setting canonical miner information: extra exceeds", params.MaximumExtraDataSize)
|
||||
glog.V(logger.Debug).Infof("extra: %x\n", extra)
|
||||
return nil
|
||||
}
|
||||
|
||||
return extra
|
||||
}
|
||||
|
||||
// makeBootstrapNodes returns default (hence bootstrap) list of peers
|
||||
func makeBootstrapNodes() []*discover.Node {
|
||||
// on desktops params.TestnetBootnodes and params.MainBootnodes,
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
whisper "github.com/ethereum/go-ethereum/whisper/whisperv2"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
// SelectedExtKey is a container for currently selected (logged in) account
|
||||
|
@ -46,7 +46,6 @@ type NodeServiceStack struct {
|
|||
}
|
||||
|
||||
var (
|
||||
ErrDataDirPreprocessingFailed = errors.New("failed to pre-process data directory")
|
||||
ErrInvalidGethNode = errors.New("no running geth node detected")
|
||||
ErrInvalidAccountManager = errors.New("could not retrieve account manager")
|
||||
ErrInvalidWhisperService = errors.New("whisper service is unavailable")
|
||||
|
@ -65,7 +64,7 @@ var (
|
|||
)
|
||||
|
||||
// CreateAndRunNode creates and starts running Geth node locally (exposing given RPC port along the way)
|
||||
func CreateAndRunNode(config *NodeConfig) error {
|
||||
func CreateAndRunNode(config *params.NodeConfig) error {
|
||||
defer HaltOnPanic()
|
||||
|
||||
nodeManager := NewNodeManager(config)
|
||||
|
@ -80,7 +79,7 @@ func CreateAndRunNode(config *NodeConfig) error {
|
|||
}
|
||||
|
||||
// NewNodeManager makes new instance of node manager
|
||||
func NewNodeManager(config *NodeConfig) *NodeManager {
|
||||
func NewNodeManager(config *params.NodeConfig) *NodeManager {
|
||||
createOnce.Do(func() {
|
||||
nodeManagerInstance = &NodeManager{
|
||||
services: &NodeServiceStack{
|
||||
|
|
|
@ -1,67 +1,28 @@
|
|||
package geth_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/status-im/status-go/geth"
|
||||
)
|
||||
|
||||
const (
|
||||
testAddress = "0xadaf150b905cf5e6a778e553e15a139b6618bbb7"
|
||||
testAddressPassword = "asdfasdf"
|
||||
newAccountPassword = "badpassword"
|
||||
testAddress1 = "0xadd4d1d02e71c7360c53296968e59d57fd15e2ba"
|
||||
|
||||
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)"
|
||||
)
|
||||
var testConfig *geth.TestConfig
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
syncRequired := false
|
||||
if _, err := os.Stat(filepath.Join(geth.TestDataDir, "testnet")); os.IsNotExist(err) {
|
||||
syncRequired = true
|
||||
}
|
||||
// make sure you panic if node start signal is not received
|
||||
signalRecieved := make(chan struct{}, 1)
|
||||
abortPanic := make(chan struct{}, 1)
|
||||
if syncRequired {
|
||||
geth.PanicAfter(geth.TestNodeSyncSeconds*time.Second, abortPanic, "TestNodeSetup")
|
||||
} else {
|
||||
geth.PanicAfter(10*time.Second, abortPanic, "TestNodeSetup")
|
||||
}
|
||||
|
||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||
var envelope geth.SignalEnvelope
|
||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||
panic(fmt.Errorf("cannot unmarshal event's JSON: %s", jsonEvent))
|
||||
}
|
||||
if envelope.Type == geth.EventNodeCrashed {
|
||||
geth.TriggerDefaultNodeNotificationHandler(jsonEvent)
|
||||
return
|
||||
}
|
||||
|
||||
if jsonEvent == `{"type":"node.started","event":{}}` {
|
||||
signalRecieved <- struct{}{}
|
||||
}
|
||||
})
|
||||
|
||||
err := geth.PrepareTestNode()
|
||||
// load shared test configuration
|
||||
var err error
|
||||
testConfig, err = geth.LoadTestConfig()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
<-signalRecieved // block and wait for either panic or successful signal
|
||||
abortPanic <- struct{}{}
|
||||
// run tests
|
||||
retCode := m.Run()
|
||||
|
||||
os.Exit(m.Run())
|
||||
//time.Sleep(25 * time.Second) // to give some time to propagate txs to the rest of the network
|
||||
os.Exit(retCode)
|
||||
}
|
||||
|
||||
func TestResetChainData(t *testing.T) {
|
||||
|
@ -77,7 +38,7 @@ func TestResetChainData(t *testing.T) {
|
|||
}
|
||||
|
||||
// allow some time to re-sync
|
||||
time.Sleep(geth.TestNodeSyncSeconds * time.Second)
|
||||
time.Sleep(testConfig.Node.SyncSeconds * time.Second)
|
||||
|
||||
// now make sure that everything is intact
|
||||
TestQueuedTransactions(t)
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package params
|
||||
|
||||
// MainnetBootnodes are the enode URLs of the P2P bootstrap nodes running on the main Ethereum network.
|
||||
var MainnetBootnodes = []string{
|
||||
}
|
||||
var MainnetBootnodes = []string{}
|
||||
|
||||
// TestnetBootnodes are the enode URLs of the P2P bootstrap nodes running on the Ropsten test network.
|
||||
var TestnetBootnodes = []string{
|
||||
|
@ -39,5 +38,4 @@ var TestnetBootnodes = []string{
|
|||
|
||||
// DiscoveryV5Bootnodes are the enode URLs of the P2P bootstrap nodes for the
|
||||
// experimental RLPx v5 topic-discovery network.
|
||||
var DiscoveryV5Bootnodes = []string{
|
||||
}
|
||||
var DiscoveryV5Bootnodes = []string{}
|
|
@ -0,0 +1,275 @@
|
|||
package params
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"math/big"
|
||||
"errors"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/logger"
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
// default node configuration options
|
||||
var (
|
||||
UseMainnetFlag = "false" // to be overridden via -ldflags '-X geth/params.UseMainnetFlag'
|
||||
UseMainnet = false
|
||||
)
|
||||
|
||||
func init() {
|
||||
if UseMainnetFlag == "true" { // set at compile time, here we make sure to set corresponding boolean flag
|
||||
UseMainnet = true
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
ErrMissingDataDir = errors.New("missing required 'DataDir' parameter")
|
||||
ErrMissingNetworkId = errors.New("missing required 'NetworkId' parameter")
|
||||
)
|
||||
|
||||
// ChainConfig holds core blockchain settings. It is stored in the database on a per block basis.
|
||||
type ChainConfig struct {
|
||||
// ChainId identifies the current chain and is used for replay protection
|
||||
ChainId *big.Int
|
||||
|
||||
// HomesteadBlock is Homestead switch block (nil = no fork, 0 = already homestead)
|
||||
HomesteadBlock *big.Int
|
||||
|
||||
// DAOForkBlock TheDAO hard-fork switch block (nil = no fork)
|
||||
DAOForkBlock *big.Int
|
||||
|
||||
// DAOForkSupport Whether the nodes supports or opposes the DAO hard-fork
|
||||
DAOForkSupport bool
|
||||
|
||||
// EIP150Block is EIP150 HF block (nil = no fork)
|
||||
EIP150Block *big.Int
|
||||
|
||||
// EIP150Hash is EIP150 HF hash (fast sync aid)
|
||||
EIP150Hash common.Hash
|
||||
|
||||
// EIP155Block is EIP155 HF block
|
||||
EIP155Block *big.Int
|
||||
|
||||
// EIP158Block is EIP158 HF block
|
||||
EIP158Block *big.Int
|
||||
}
|
||||
|
||||
// LightEthConfig holds LES-related configuration
|
||||
// Status nodes are always lightweight clients (due to mobile platform constraints)
|
||||
type LightEthConfig struct {
|
||||
// Genesis is JSON to seed the chain database with
|
||||
Genesis string
|
||||
|
||||
// DatabaseCache is memory (in MBs) allocated to internal caching (min 16MB / database forced)
|
||||
DatabaseCache int
|
||||
}
|
||||
|
||||
// WhisperConfig holds SHH-related configuration
|
||||
type WhisperConfig struct{}
|
||||
|
||||
// SwarmConfig holds Swarm-related configuration
|
||||
type SwarmConfig struct{}
|
||||
|
||||
// NodeConfig stores configuration options for a node
|
||||
type NodeConfig struct {
|
||||
// TestNet flag whether given configuration describes a test or mainnet
|
||||
TestNet bool
|
||||
|
||||
// NetworkId sets network to use for selecting peers to connect to
|
||||
NetworkId int
|
||||
|
||||
// DataDir is the file system folder the node should use for any data storage needs.
|
||||
DataDir string
|
||||
|
||||
// Name sets the instance name of the node. It must not contain the / character.
|
||||
Name string
|
||||
|
||||
// Version exposes program's version. It is used in the devp2p node identifier.
|
||||
Version string
|
||||
|
||||
// APIModules is a comma-separated list of API modules exposed via *any* (HTTP/WS/IPC) RPC interface.
|
||||
APIModules string
|
||||
|
||||
// HTTPHost is the host interface on which to start the HTTP RPC server.
|
||||
// Pass empty string if no HTTP RPC interface needs to be started.
|
||||
HTTPHost string
|
||||
|
||||
// HTTPPort is the TCP port number on which to start the Geth's HTTP RPC server.
|
||||
HTTPPort int
|
||||
|
||||
// WSHost is a host interface for the WebSocket RPC server
|
||||
WSHost string
|
||||
|
||||
// WSPort is the TCP port number on which to start the Geth's WebSocket RPC server.
|
||||
WSPort int
|
||||
|
||||
// WSEnabled specifies whether WS-RPC Server is enabled or not
|
||||
WSEnabled bool
|
||||
|
||||
// IPCFile is filename of exposed IPC RPC Server
|
||||
IPCFile string
|
||||
|
||||
// IPCEnabled specifies whether IPC-RPC Server is enabled or not
|
||||
IPCEnabled bool
|
||||
|
||||
// TLSEnabled specifies whether TLS support should be enabled on node or not
|
||||
// TLS support is only planned in go-ethereum, so we are using our own patch.
|
||||
TLSEnabled bool
|
||||
|
||||
// MaxPeers is the maximum number of (global) peers that can be connected.
|
||||
// Set to zero, if only static or trusted peers are allowed to connect.
|
||||
MaxPeers int
|
||||
|
||||
// MaxPendingPeers is the maximum number of peers that can be pending in the
|
||||
// handshake phase, counted separately for inbound and outbound connections.
|
||||
MaxPendingPeers int
|
||||
|
||||
// ChainConfig extra configuration for blockchain
|
||||
*ChainConfig `json:"ChainConfig,"`
|
||||
|
||||
// LightEthConfig extra configuration for LES
|
||||
*LightEthConfig `json:"LightEthConfig,"`
|
||||
|
||||
// WhisperConfig extra configuration for SHH
|
||||
*WhisperConfig `json:"WhisperConfig,"`
|
||||
|
||||
// SwarmConfig extra configuration for Swarm and ENS
|
||||
*SwarmConfig `json:"SwarmConfig,"`
|
||||
}
|
||||
|
||||
// NewNodeConfig creates new node configuration object
|
||||
func NewNodeConfig(dataDir string, networkId int) (*NodeConfig, error) {
|
||||
nodeConfig := &NodeConfig{
|
||||
NetworkId: networkId,
|
||||
DataDir: dataDir,
|
||||
Name: DefaultClientIdentifier,
|
||||
Version: Version,
|
||||
HTTPHost: DefaultHTTPHost,
|
||||
HTTPPort: DefaultHTTPPort,
|
||||
APIModules: DefaultAPIModules,
|
||||
WSHost: DefaultWSHost,
|
||||
WSPort: DefaultWSPort,
|
||||
MaxPeers: DefaultMaxPeers,
|
||||
MaxPendingPeers: DefaultMaxPendingPeers,
|
||||
IPCFile: DefaultIPCFile,
|
||||
ChainConfig: &ChainConfig{},
|
||||
LightEthConfig: &LightEthConfig{
|
||||
DatabaseCache: DefaultDatabaseCache,
|
||||
},
|
||||
WhisperConfig: &WhisperConfig{},
|
||||
SwarmConfig: &SwarmConfig{},
|
||||
}
|
||||
|
||||
nodeConfig.populateChainConfig()
|
||||
|
||||
return nodeConfig, nil
|
||||
}
|
||||
|
||||
// populateChainConfig does necessary adjustments to config object (depending on network node will be runnin on)
|
||||
func (c *NodeConfig) populateChainConfig() {
|
||||
c.TestNet = false
|
||||
if c.NetworkId == TestNetworkId {
|
||||
c.TestNet = true
|
||||
}
|
||||
|
||||
if c.TestNet {
|
||||
// Homestead fork
|
||||
c.ChainConfig.HomesteadBlock = params.TestnetChainConfig.HomesteadBlock
|
||||
|
||||
// DAO fork
|
||||
c.ChainConfig.DAOForkBlock = params.TestnetChainConfig.DAOForkBlock
|
||||
c.ChainConfig.DAOForkSupport = params.TestnetChainConfig.DAOForkSupport
|
||||
|
||||
// DoS reprice fork
|
||||
c.ChainConfig.EIP150Block = params.TestnetChainConfig.EIP150Block
|
||||
c.ChainConfig.EIP150Hash = params.TestnetChainConfig.EIP150Hash
|
||||
|
||||
// DoS state cleanup fork
|
||||
c.ChainConfig.EIP155Block = params.TestnetChainConfig.EIP155Block
|
||||
c.ChainConfig.EIP158Block = params.TestnetChainConfig.EIP158Block
|
||||
c.ChainConfig.ChainId = params.TestnetChainConfig.ChainId
|
||||
|
||||
if len(c.DataDir) > 0 {
|
||||
c.DataDir = filepath.Join(c.DataDir, "testnet")
|
||||
}
|
||||
c.Genesis = core.DefaultTestnetGenesisBlock()
|
||||
} else {
|
||||
// Homestead fork
|
||||
c.ChainConfig.HomesteadBlock = params.MainNetHomesteadBlock
|
||||
// DAO fork
|
||||
c.ChainConfig.DAOForkBlock = params.MainNetDAOForkBlock
|
||||
c.ChainConfig.DAOForkSupport = true
|
||||
|
||||
// DoS reprice fork
|
||||
c.ChainConfig.EIP150Block = params.MainNetHomesteadGasRepriceBlock
|
||||
c.ChainConfig.EIP150Hash = params.MainNetHomesteadGasRepriceHash
|
||||
|
||||
// DoS state cleanup fork
|
||||
c.ChainConfig.EIP155Block = params.MainNetSpuriousDragon
|
||||
c.ChainConfig.EIP158Block = params.MainNetSpuriousDragon
|
||||
c.ChainConfig.ChainId = params.MainNetChainID
|
||||
|
||||
c.Genesis = core.DefaultGenesisBlock()
|
||||
}
|
||||
}
|
||||
|
||||
// LoadNodeConfig parses incoming JSON and returned it as Config
|
||||
func LoadNodeConfig(configJSON string) (*NodeConfig, error) {
|
||||
nodeConfig, err := NewNodeConfig("", 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(strings.NewReader(configJSON))
|
||||
//decoder.UseNumber()
|
||||
|
||||
// override default configuration with values by JSON input
|
||||
if err := decoder.Decode(&nodeConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// repopulate
|
||||
nodeConfig.populateChainConfig()
|
||||
|
||||
if len(nodeConfig.DataDir) == 0 {
|
||||
return nil, ErrMissingDataDir
|
||||
}
|
||||
|
||||
if nodeConfig.NetworkId <= 0 {
|
||||
return nil, ErrMissingNetworkId
|
||||
}
|
||||
|
||||
return nodeConfig, nil
|
||||
}
|
||||
|
||||
// Save dumps configuration to the disk
|
||||
func (c *NodeConfig) Save() error {
|
||||
data, err := json.MarshalIndent(c, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(c.DataDir, os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
configFilePath := filepath.Join(c.DataDir, "config.json")
|
||||
if err := ioutil.WriteFile(configFilePath, data, os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
glog.V(logger.Info).Infof("config file saved: %v", configFilePath)
|
||||
return nil
|
||||
}
|
||||
|
||||
// String dumps config object as nicely indented JSON
|
||||
func (c *NodeConfig) String() string {
|
||||
data, _ := json.MarshalIndent(c, "", " ")
|
||||
return string(data)
|
||||
}
|
|
@ -0,0 +1,319 @@
|
|||
package params_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/status-im/status-go/geth"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
gethparams "github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
var loadConfigTestCases = []struct {
|
||||
name string
|
||||
configJSON string
|
||||
validator func(t *testing.T, dataDir string, nodeConfig *params.NodeConfig, err error)
|
||||
}{
|
||||
{
|
||||
`invalid input configuration`,
|
||||
`{
|
||||
"NetworkId": 3
|
||||
"DataDir": "$TMPDIR",
|
||||
"Name": "TestStatusNode",
|
||||
"WSPort": 8546,
|
||||
"IPCEnabled": true,
|
||||
"WSEnabled": false,
|
||||
"LightEthConfig": {
|
||||
"DatabaseCache": 64
|
||||
}
|
||||
}`,
|
||||
func(t *testing.T, dataDir string, nodeConfig *params.NodeConfig, err error) {
|
||||
if err == nil {
|
||||
t.Fatal("error is expected, not thrown")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
`missing required field (DataDir)`,
|
||||
`{
|
||||
"NetworkId": 3,
|
||||
"Name": "TestStatusNode"
|
||||
}`,
|
||||
func(t *testing.T, dataDir string, nodeConfig *params.NodeConfig, err error) {
|
||||
if err != params.ErrMissingDataDir {
|
||||
t.Fatalf("expected error not thrown, expected: %v, thrown: %v", params.ErrMissingDataDir, err)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
`missing required field (NetworkId)`,
|
||||
`{
|
||||
"DataDir": "$TMPDIR"
|
||||
}`,
|
||||
func(t *testing.T, dataDir string, nodeConfig *params.NodeConfig, err error) {
|
||||
if err != params.ErrMissingNetworkId {
|
||||
t.Fatalf("expected error not thrown, expected: %v, thrown: %v", params.ErrMissingNetworkId, err)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
`testnet subdirectory not used (while we are on Network = 3)`,
|
||||
`{
|
||||
"NetworkId": 3,
|
||||
"DataDir": "$TMPDIR"
|
||||
}`,
|
||||
func(t *testing.T, dataDir string, nodeConfig *params.NodeConfig, err error) {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if nodeConfig.DataDir != filepath.Join(dataDir, "testnet") {
|
||||
t.Fatal("'testnet' subdirectory not used")
|
||||
}
|
||||
|
||||
if !strings.Contains(nodeConfig.LightEthConfig.Genesis, "\"chainId\": 3") {
|
||||
t.Fatal("wrong genesis")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
`testnet subdirectory used (while we are on Network != 3)`,
|
||||
`{
|
||||
"NetworkId": 1,
|
||||
"DataDir": "$TMPDIR"
|
||||
}`,
|
||||
func(t *testing.T, dataDir string, nodeConfig *params.NodeConfig, err error) {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if nodeConfig.DataDir != dataDir {
|
||||
t.Fatal("'testnet' subdirectory used")
|
||||
}
|
||||
|
||||
if strings.Contains(nodeConfig.LightEthConfig.Genesis, "\"chainId\": 3") {
|
||||
t.Fatal("wrong genesis")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
`test parameter overriding`,
|
||||
`{
|
||||
"NetworkId": 3,
|
||||
"DataDir": "$TMPDIR",
|
||||
"Name": "TestStatusNode",
|
||||
"WSPort": 4242,
|
||||
"IPCEnabled": true,
|
||||
"WSEnabled": false,
|
||||
"LightEthConfig": {
|
||||
"DatabaseCache": 64
|
||||
}
|
||||
}`,
|
||||
func(t *testing.T, dataDir string, nodeConfig *params.NodeConfig, err error) {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if nodeConfig.NetworkId != 3 {
|
||||
t.Fatal("wrong NetworkId")
|
||||
}
|
||||
|
||||
if nodeConfig.Name != "TestStatusNode" {
|
||||
t.Fatal("wrong Name")
|
||||
}
|
||||
|
||||
if nodeConfig.HTTPPort != params.DefaultHTTPPort {
|
||||
t.Fatal("wrong HTTPPort")
|
||||
}
|
||||
|
||||
if nodeConfig.HTTPHost != params.DefaultHTTPHost {
|
||||
t.Fatal("wrong HTTPHost")
|
||||
}
|
||||
|
||||
if nodeConfig.WSPort != 4242 {
|
||||
t.Fatal("wrong WSPort")
|
||||
}
|
||||
|
||||
if nodeConfig.WSEnabled != false {
|
||||
t.Fatal("wrong WSEnabled")
|
||||
}
|
||||
|
||||
if nodeConfig.IPCEnabled != true{
|
||||
t.Fatal("wrong IPCEnabled")
|
||||
}
|
||||
if nodeConfig.LightEthConfig.DatabaseCache != 64 {
|
||||
t.Fatal("wrong LightEthConfig.DatabaseCache")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
`test loading Testnet config`,
|
||||
`{
|
||||
"NetworkId": 3,
|
||||
"DataDir": "$TMPDIR",
|
||||
"Name": "TestStatusNode",
|
||||
"WSPort": 8546,
|
||||
"IPCEnabled": true,
|
||||
"WSEnabled": false,
|
||||
"LightEthConfig": {
|
||||
"DatabaseCache": 64
|
||||
}
|
||||
}`,
|
||||
func(t *testing.T, dataDir string, nodeConfig *params.NodeConfig, err error) {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
chainConfig := nodeConfig.ChainConfig
|
||||
refChainConfig := gethparams.TestnetChainConfig
|
||||
|
||||
if chainConfig.HomesteadBlock.Cmp(refChainConfig.HomesteadBlock) != 0 {
|
||||
t.Fatal("invalid chainConfig.HomesteadBlock")
|
||||
}
|
||||
if chainConfig.DAOForkBlock != nil { // already forked
|
||||
t.Fatal("invalid chainConfig.DAOForkBlock")
|
||||
}
|
||||
if chainConfig.DAOForkSupport != refChainConfig.DAOForkSupport {
|
||||
t.Fatal("invalid chainConfig.DAOForkSupport")
|
||||
}
|
||||
if chainConfig.EIP150Block.Cmp(refChainConfig.EIP150Block) != 0 {
|
||||
t.Fatal("invalid chainConfig.EIP150Block")
|
||||
}
|
||||
if chainConfig.EIP150Hash != refChainConfig.EIP150Hash {
|
||||
t.Fatal("invalid chainConfig.EIP150Hash")
|
||||
}
|
||||
if chainConfig.EIP155Block.Cmp(refChainConfig.EIP155Block) != 0 {
|
||||
t.Fatal("invalid chainConfig.EIP155Block")
|
||||
}
|
||||
if chainConfig.EIP158Block.Cmp(refChainConfig.EIP158Block) != 0 {
|
||||
t.Fatal("invalid chainConfig.EIP158Block")
|
||||
}
|
||||
if chainConfig.ChainId.Cmp(refChainConfig.ChainId) != 0 {
|
||||
t.Fatal("invalid chainConfig.ChainId")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
`test loading Mainnet config`,
|
||||
`{
|
||||
"NetworkId": 1,
|
||||
"DataDir": "$TMPDIR",
|
||||
"Name": "TestStatusNode",
|
||||
"WSPort": 8546,
|
||||
"IPCEnabled": true,
|
||||
"WSEnabled": false,
|
||||
"LightEthConfig": {
|
||||
"DatabaseCache": 64
|
||||
}
|
||||
}`,
|
||||
func(t *testing.T, dataDir string, nodeConfig *params.NodeConfig, err error) {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
chainConfig := nodeConfig.ChainConfig
|
||||
if chainConfig.HomesteadBlock.Cmp(gethparams.MainNetHomesteadBlock) != 0 {
|
||||
t.Fatal("invalid chainConfig.HomesteadBlock")
|
||||
}
|
||||
if chainConfig.DAOForkBlock.Cmp(gethparams.MainNetDAOForkBlock) != 0 {
|
||||
t.Fatal("invalid chainConfig.DAOForkBlock")
|
||||
}
|
||||
if chainConfig.DAOForkSupport != true {
|
||||
t.Fatal("invalid chainConfig.DAOForkSupport")
|
||||
}
|
||||
if chainConfig.EIP150Block.Cmp(gethparams.MainNetHomesteadGasRepriceBlock) != 0 {
|
||||
t.Fatal("invalid chainConfig.EIP150Block")
|
||||
}
|
||||
if chainConfig.EIP150Hash != gethparams.MainNetHomesteadGasRepriceHash {
|
||||
t.Fatal("invalid chainConfig.EIP150Hash")
|
||||
}
|
||||
if chainConfig.EIP155Block.Cmp(gethparams.MainNetSpuriousDragon) != 0 {
|
||||
t.Fatal("invalid chainConfig.EIP155Block")
|
||||
}
|
||||
if chainConfig.EIP158Block.Cmp(gethparams.MainNetSpuriousDragon) != 0 {
|
||||
t.Fatal("invalid chainConfig.EIP158Block")
|
||||
}
|
||||
if chainConfig.ChainId.Cmp(gethparams.MainNetChainID) != 0 {
|
||||
t.Fatal("invalid chainConfig.ChainId")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
`test loading Privatenet config`,
|
||||
`{
|
||||
"NetworkId": 311,
|
||||
"DataDir": "$TMPDIR",
|
||||
"Name": "TestStatusNode",
|
||||
"WSPort": 8546,
|
||||
"IPCEnabled": true,
|
||||
"WSEnabled": false,
|
||||
"ChainConfig": {
|
||||
"ChainId": 311
|
||||
}
|
||||
}`,
|
||||
func(t *testing.T, dataDir string, nodeConfig *params.NodeConfig, err error) {
|
||||
//nodeConfig.LightEthConfig.Genesis = nodeConfig.LightEthConfig.Genesis[:125]
|
||||
//fmt.Println(nodeConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
networkId := 311
|
||||
|
||||
if nodeConfig.NetworkId != networkId {
|
||||
t.Fatalf("unexpected NetworkId, expected: %v, got: %v", networkId, nodeConfig.NetworkId)
|
||||
}
|
||||
|
||||
if nodeConfig.ChainId.Int64() != int64(networkId) {
|
||||
t.Fatalf("unexpected ChainConfig.ChainId, expected: %v, got: %v", networkId, nodeConfig.ChainId)
|
||||
}
|
||||
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestLoadNodeConfig(t *testing.T) {
|
||||
tmpDir, err := ioutil.TempDir(os.TempDir(), "geth-config-tests")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
for _, testCase := range loadConfigTestCases {
|
||||
t.Log("test: " + testCase.name)
|
||||
testCase.configJSON = strings.Replace(testCase.configJSON, "$TMPDIR", tmpDir, -1)
|
||||
nodeConfig, err := params.LoadNodeConfig(testCase.configJSON)
|
||||
testCase.validator(t, tmpDir, nodeConfig, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigWriteRead(t *testing.T) {
|
||||
tmpDir, err := ioutil.TempDir(os.TempDir(), "geth-config-tests")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
nodeConfig, err := params.NewNodeConfig(tmpDir, params.TestNetworkId)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot create new config object: %v", err)
|
||||
}
|
||||
|
||||
if err := nodeConfig.Save(); err != nil {
|
||||
t.Fatalf("cannot persist configuration: %v", err)
|
||||
}
|
||||
|
||||
loadedConfigData, err := ioutil.ReadFile(filepath.Join(nodeConfig.DataDir, "config.json"))
|
||||
if err != nil {
|
||||
t.Fatalf("cannot read configuration from disk: %v", err)
|
||||
}
|
||||
|
||||
refConfigData := geth.LoadFromFile("testdata/config.testnet.json")
|
||||
|
||||
refConfigData = strings.Replace(refConfigData, "$TMPDIR", nodeConfig.DataDir, -1)
|
||||
refConfigData = strings.Replace(refConfigData, "$VERSION", params.Version, -1)
|
||||
if string(loadedConfigData) != refConfigData {
|
||||
t.Fatalf("configuration mismatch,\nexpected: %v\ngot: %v", refConfigData, string(loadedConfigData))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package params
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultClientIdentifier is client identifier to advertise over the network
|
||||
DefaultClientIdentifier = "status"
|
||||
|
||||
// DefaultIPCFile is filename of exposed IPC RPC Server
|
||||
DefaultIPCFile = "geth.ipc"
|
||||
|
||||
// DefaultHTTPHost is host interface for the HTTP RPC server
|
||||
DefaultHTTPHost = "localhost"
|
||||
|
||||
// DefaultHTTPPort is HTTP-RPC port (replaced in unit tests)
|
||||
DefaultHTTPPort = 8545
|
||||
|
||||
// DefaultAPIModules is a list of modules to expose vie HTTP RPC
|
||||
// TODO remove "admin" on main net
|
||||
DefaultAPIModules = "db,eth,net,web3,shh,personal,admin"
|
||||
|
||||
// DefaultWSHost is a host interface for the websocket RPC server
|
||||
DefaultWSHost = "localhost"
|
||||
|
||||
// DefaultWSPort is a WS-RPC port (replaced in unit tests)
|
||||
DefaultWSPort = 8546
|
||||
|
||||
// DefaultMaxPeers is the maximum number of global peers
|
||||
DefaultMaxPeers = 25
|
||||
|
||||
// DefaultMaxPendingPeers is the maximum number of peers that can be pending in the
|
||||
// handshake phase, counted separately for inbound and outbound connections.
|
||||
DefaultMaxPendingPeers = 0
|
||||
|
||||
// DefaultGas default amount of gas used for transactions
|
||||
DefaultGas = 180000
|
||||
|
||||
// DefaultFileDescriptorLimit is fd limit that database can use
|
||||
DefaultFileDescriptorLimit = uint64(2048)
|
||||
|
||||
// DefaultDatabaseCache is memory (in MBs) allocated to internal caching (min 16MB / database forced)
|
||||
DefaultDatabaseCache = 128
|
||||
|
||||
// TestNetworkId is id of a test network
|
||||
TestNetworkId = 3
|
||||
)
|
||||
|
||||
// Gas price settings
|
||||
var (
|
||||
GasPrice = new(big.Int).Mul(big.NewInt(20), common.Shannon) // Minimal gas price to accept for mining a transactions
|
||||
GpoMinGasPrice = new(big.Int).Mul(big.NewInt(20), common.Shannon) // Minimum suggested gas price
|
||||
GpoMaxGasPrice = new(big.Int).Mul(big.NewInt(500), common.Shannon) // Maximum suggested gas price
|
||||
GpoFullBlockRatio = 80 // Full block threshold for gas price calculation (%)
|
||||
GpobaseStepDown = 10 // Suggested gas price base step down ratio (1/1000)
|
||||
GpobaseStepUp = 100 // Suggested gas price base step up ratio (1/1000)
|
||||
GpobaseCorrectionFactor = 110 // Suggested gas price base correction factor (%)
|
||||
)
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/les/status"
|
||||
"github.com/status-im/status-go/geth"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
func TestQueuedContracts(t *testing.T) {
|
||||
|
@ -30,7 +31,7 @@ func TestQueuedContracts(t *testing.T) {
|
|||
backend := lightEthereum.StatusBackend
|
||||
|
||||
// create an account
|
||||
sampleAddress, _, _, err := geth.CreateAccount(newAccountPassword)
|
||||
sampleAddress, _, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return
|
||||
|
@ -40,7 +41,7 @@ func TestQueuedContracts(t *testing.T) {
|
|||
|
||||
// make sure you panic if transaction complete doesn't return
|
||||
completeQueuedTransaction := make(chan struct{}, 1)
|
||||
geth.PanicAfter(60*time.Second, completeQueuedTransaction, "TestQueuedContracts")
|
||||
geth.PanicAfter(5*time.Second, completeQueuedTransaction, "TestQueuedContracts")
|
||||
|
||||
// replace transaction notification handler
|
||||
var txHash = common.Hash{}
|
||||
|
@ -52,37 +53,36 @@ func TestQueuedContracts(t *testing.T) {
|
|||
}
|
||||
if envelope.Type == geth.EventTransactionQueued {
|
||||
event := envelope.Event.(map[string]interface{})
|
||||
t.Logf("transaction queued (will be completed in 5 secs): {id: %s}\n", event["id"].(string))
|
||||
time.Sleep(5 * time.Second)
|
||||
t.Logf("transaction queued (will be completed shortly): {id: %s}\n", event["id"].(string))
|
||||
|
||||
// the first call will fail (we are not logged in, but trying to complete tx)
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testAddressPassword); err != status.ErrInvalidCompleteTxSender {
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testConfig.Account1.Password); err != status.ErrInvalidCompleteTxSender {
|
||||
t.Errorf("expected error on queued transation[%v] not thrown: expected %v, got %v", event["id"], status.ErrInvalidCompleteTxSender, err)
|
||||
return
|
||||
}
|
||||
|
||||
// the second call will also fail (we are logged in as different user)
|
||||
if err := geth.SelectAccount(sampleAddress, newAccountPassword); err != nil {
|
||||
if err := geth.SelectAccount(sampleAddress, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", sampleAddress)
|
||||
return
|
||||
}
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testAddressPassword); err != status.ErrInvalidCompleteTxSender {
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testConfig.Account1.Password); err != status.ErrInvalidCompleteTxSender {
|
||||
t.Errorf("expected error on queued transation[%v] not thrown: expected %v, got %v", event["id"], status.ErrInvalidCompleteTxSender, err)
|
||||
return
|
||||
}
|
||||
|
||||
// the third call will work as expected (as we are logged in with correct credentials)
|
||||
if err := geth.SelectAccount(testAddress, testAddressPassword); err != nil {
|
||||
t.Errorf("cannot select account: %v", testAddress)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return
|
||||
}
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testAddressPassword); err != nil {
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot complete queued transation[%v]: %v", event["id"], err)
|
||||
return
|
||||
}
|
||||
|
||||
t.Logf("contract transaction complete: https://testnet.etherscan.io/tx/%s", txHash.Hex())
|
||||
completeQueuedTransaction <- struct{}{} // so that timeout is aborted
|
||||
close(completeQueuedTransaction)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -93,10 +93,10 @@ func TestQueuedContracts(t *testing.T) {
|
|||
return
|
||||
}
|
||||
txHashCheck, err := backend.SendTransaction(nil, status.SendTxArgs{
|
||||
From: geth.FromAddress(testAddress),
|
||||
From: geth.FromAddress(testConfig.Account1.Address),
|
||||
To: nil, // marker, contract creation is expected
|
||||
//Value: (*hexutil.Big)(new(big.Int).Mul(big.NewInt(1), common.Ether)),
|
||||
Gas: (*hexutil.Big)(big.NewInt(geth.DefaultGas)),
|
||||
Gas: (*hexutil.Big)(big.NewInt(params.DefaultGas)),
|
||||
Data: byteCode,
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -108,7 +108,7 @@ func TestQueuedContracts(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
time.Sleep(10 * time.Second)
|
||||
<-completeQueuedTransaction
|
||||
|
||||
if reflect.DeepEqual(txHashCheck, common.Hash{}) {
|
||||
t.Error("Test failed: transaction was never queued or completed")
|
||||
|
@ -137,7 +137,7 @@ func TestQueuedTransactions(t *testing.T) {
|
|||
backend := lightEthereum.StatusBackend
|
||||
|
||||
// create an account
|
||||
sampleAddress, _, _, err := geth.CreateAccount(newAccountPassword)
|
||||
sampleAddress, _, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return
|
||||
|
@ -147,7 +147,7 @@ func TestQueuedTransactions(t *testing.T) {
|
|||
|
||||
// make sure you panic if transaction complete doesn't return
|
||||
completeQueuedTransaction := make(chan struct{}, 1)
|
||||
geth.PanicAfter(60*time.Second, completeQueuedTransaction, "TestQueuedTransactions")
|
||||
geth.PanicAfter(5*time.Second, completeQueuedTransaction, "TestQueuedTransactions")
|
||||
|
||||
// replace transaction notification handler
|
||||
var txHash = common.Hash{}
|
||||
|
@ -159,44 +159,43 @@ func TestQueuedTransactions(t *testing.T) {
|
|||
}
|
||||
if envelope.Type == geth.EventTransactionQueued {
|
||||
event := envelope.Event.(map[string]interface{})
|
||||
t.Logf("transaction queued (will be completed in 5 secs): {id: %s}\n", event["id"].(string))
|
||||
time.Sleep(5 * time.Second)
|
||||
t.Logf("transaction queued (will be completed shortly): {id: %s}\n", event["id"].(string))
|
||||
|
||||
// the first call will fail (we are not logged in, but trying to complete tx)
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testAddressPassword); err != status.ErrInvalidCompleteTxSender {
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testConfig.Account1.Password); err != status.ErrInvalidCompleteTxSender {
|
||||
t.Errorf("expected error on queued transation[%v] not thrown: expected %v, got %v", event["id"], status.ErrInvalidCompleteTxSender, err)
|
||||
return
|
||||
}
|
||||
|
||||
// the second call will also fail (we are logged in as different user)
|
||||
if err := geth.SelectAccount(sampleAddress, newAccountPassword); err != nil {
|
||||
if err := geth.SelectAccount(sampleAddress, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", sampleAddress)
|
||||
return
|
||||
}
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testAddressPassword); err != status.ErrInvalidCompleteTxSender {
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testConfig.Account1.Password); err != status.ErrInvalidCompleteTxSender {
|
||||
t.Errorf("expected error on queued transation[%v] not thrown: expected %v, got %v", event["id"], status.ErrInvalidCompleteTxSender, err)
|
||||
return
|
||||
}
|
||||
|
||||
// the third call will work as expected (as we are logged in with correct credentials)
|
||||
if err := geth.SelectAccount(testAddress, testAddressPassword); err != nil {
|
||||
t.Errorf("cannot select account: %v", testAddress)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return
|
||||
}
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testAddressPassword); err != nil {
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot complete queued transation[%v]: %v", event["id"], err)
|
||||
return
|
||||
}
|
||||
|
||||
t.Logf("transaction complete: https://testnet.etherscan.io/tx/%s", txHash.Hex())
|
||||
completeQueuedTransaction <- struct{}{} // so that timeout is aborted
|
||||
close(completeQueuedTransaction)
|
||||
}
|
||||
})
|
||||
|
||||
// this call blocks, up until Complete Transaction is called
|
||||
txHashCheck, err := backend.SendTransaction(nil, status.SendTxArgs{
|
||||
From: geth.FromAddress(testAddress),
|
||||
To: geth.ToAddress(testAddress1),
|
||||
From: geth.FromAddress(testConfig.Account1.Address),
|
||||
To: geth.ToAddress(testConfig.Account2.Address),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -208,7 +207,7 @@ func TestQueuedTransactions(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
time.Sleep(10 * time.Second)
|
||||
<-completeQueuedTransaction
|
||||
|
||||
if reflect.DeepEqual(txHashCheck, common.Hash{}) {
|
||||
t.Error("Test failed: transaction was never queued or completed")
|
||||
|
@ -237,8 +236,8 @@ func TestDoubleCompleteQueuedTransactions(t *testing.T) {
|
|||
backend := lightEthereum.StatusBackend
|
||||
|
||||
// log into account from which transactions will be sent
|
||||
if err := geth.SelectAccount(testAddress, testAddressPassword); err != nil {
|
||||
t.Errorf("cannot select account: %v", testAddress)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -263,21 +262,18 @@ func TestDoubleCompleteQueuedTransactions(t *testing.T) {
|
|||
|
||||
// try with wrong password
|
||||
// make sure that tx is NOT removed from the queue (by re-trying with the correct password)
|
||||
if _, err = geth.CompleteTransaction(txId, testAddressPassword+"wrong"); err != keystore.ErrDecrypt {
|
||||
if _, err = geth.CompleteTransaction(txId, testConfig.Account1.Password+"wrong"); err != keystore.ErrDecrypt {
|
||||
t.Errorf("expects wrong password error, but call succeeded (or got another error: %v)", err)
|
||||
return
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Second) // make sure that tx complete signal propagates
|
||||
if txCount := backend.TransactionQueue().Count(); txCount != 1 {
|
||||
t.Errorf("txqueue cannot be empty, as tx has failed: expected = 1, got = %d", txCount)
|
||||
return
|
||||
}
|
||||
|
||||
// now try to complete transaction, but with the correct password
|
||||
t.Log("allow 5 seconds before sedning the second CompleteTransaction")
|
||||
time.Sleep(5 * time.Second)
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testAddressPassword); err != nil {
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot complete queued transation[%v]: %v", event["id"], err)
|
||||
return
|
||||
}
|
||||
|
@ -315,8 +311,8 @@ func TestDoubleCompleteQueuedTransactions(t *testing.T) {
|
|||
|
||||
// this call blocks, and should return on *second* attempt to CompleteTransaction (w/ the correct password)
|
||||
txHashCheck, err := backend.SendTransaction(nil, status.SendTxArgs{
|
||||
From: geth.FromAddress(testAddress),
|
||||
To: geth.ToAddress(testAddress1),
|
||||
From: geth.FromAddress(testConfig.Account1.Address),
|
||||
To: geth.ToAddress(testConfig.Account2.Address),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -343,9 +339,6 @@ func TestDoubleCompleteQueuedTransactions(t *testing.T) {
|
|||
t.Error("expected tx failure signal is not received")
|
||||
return
|
||||
}
|
||||
|
||||
t.Log("sleep extra time, to allow sync")
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
|
||||
func TestDiscardQueuedTransactions(t *testing.T) {
|
||||
|
@ -367,8 +360,8 @@ func TestDiscardQueuedTransactions(t *testing.T) {
|
|||
backend.TransactionQueue().Reset()
|
||||
|
||||
// log into account from which transactions will be sent
|
||||
if err := geth.SelectAccount(testAddress, testAddressPassword); err != nil {
|
||||
t.Errorf("cannot select account: %v", testAddress)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -403,7 +396,7 @@ func TestDiscardQueuedTransactions(t *testing.T) {
|
|||
}
|
||||
|
||||
// try completing discarded transaction
|
||||
_, err = geth.CompleteTransaction(txId, testAddressPassword)
|
||||
_, err = geth.CompleteTransaction(txId, testConfig.Account1.Password)
|
||||
if err.Error() != "transaction hash not found" {
|
||||
t.Error("expects tx not found, but call to CompleteTransaction succeeded")
|
||||
return
|
||||
|
@ -441,8 +434,8 @@ func TestDiscardQueuedTransactions(t *testing.T) {
|
|||
|
||||
// this call blocks, and should return when DiscardQueuedTransaction() is called
|
||||
txHashCheck, err := backend.SendTransaction(nil, status.SendTxArgs{
|
||||
From: geth.FromAddress(testAddress),
|
||||
To: geth.ToAddress(testAddress1),
|
||||
From: geth.FromAddress(testConfig.Account1.Address),
|
||||
To: geth.ToAddress(testConfig.Account2.Address),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
})
|
||||
if err != status.ErrQueuedTxDiscarded {
|
||||
|
@ -464,9 +457,6 @@ func TestDiscardQueuedTransactions(t *testing.T) {
|
|||
t.Error("expected tx failure signal is not received")
|
||||
return
|
||||
}
|
||||
|
||||
t.Log("sleep extra time, to allow sync")
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
|
||||
func TestCompleteMultipleQueuedTransactions(t *testing.T) {
|
||||
|
@ -488,8 +478,8 @@ func TestCompleteMultipleQueuedTransactions(t *testing.T) {
|
|||
backend.TransactionQueue().Reset()
|
||||
|
||||
// log into account from which transactions will be sent
|
||||
if err := geth.SelectAccount(testAddress, testAddressPassword); err != nil {
|
||||
t.Errorf("cannot select account: %v", testAddress)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -518,8 +508,8 @@ func TestCompleteMultipleQueuedTransactions(t *testing.T) {
|
|||
// this call blocks, and should return when DiscardQueuedTransaction() for a given tx id is called
|
||||
sendTx := func() {
|
||||
txHashCheck, err := backend.SendTransaction(nil, status.SendTxArgs{
|
||||
From: geth.FromAddress(testAddress),
|
||||
To: geth.ToAddress(testAddress1),
|
||||
From: geth.FromAddress(testConfig.Account1.Address),
|
||||
To: geth.ToAddress(testConfig.Account2.Address),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -542,7 +532,7 @@ func TestCompleteMultipleQueuedTransactions(t *testing.T) {
|
|||
updatedTxIdStrings, _ := json.Marshal(parsedIds)
|
||||
|
||||
// complete
|
||||
results := geth.CompleteTransactions(string(updatedTxIdStrings), testAddressPassword)
|
||||
results := geth.CompleteTransactions(string(updatedTxIdStrings), testConfig.Account1.Password)
|
||||
if len(results) != (testTxCount+1) || results["invalid-tx-id"].Error.Error() != "transaction hash not found" {
|
||||
t.Errorf("cannot complete txs: %v", results)
|
||||
return
|
||||
|
@ -619,8 +609,8 @@ func TestDiscardMultipleQueuedTransactions(t *testing.T) {
|
|||
backend.TransactionQueue().Reset()
|
||||
|
||||
// log into account from which transactions will be sent
|
||||
if err := geth.SelectAccount(testAddress, testAddressPassword); err != nil {
|
||||
t.Errorf("cannot select account: %v", testAddress)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -678,8 +668,8 @@ func TestDiscardMultipleQueuedTransactions(t *testing.T) {
|
|||
// this call blocks, and should return when DiscardQueuedTransaction() for a given tx id is called
|
||||
sendTx := func() {
|
||||
txHashCheck, err := backend.SendTransaction(nil, status.SendTxArgs{
|
||||
From: geth.FromAddress(testAddress),
|
||||
To: geth.ToAddress(testAddress1),
|
||||
From: geth.FromAddress(testConfig.Account1.Address),
|
||||
To: geth.ToAddress(testConfig.Account2.Address),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
})
|
||||
if err != status.ErrQueuedTxDiscarded {
|
||||
|
@ -709,7 +699,7 @@ func TestDiscardMultipleQueuedTransactions(t *testing.T) {
|
|||
}
|
||||
|
||||
// try completing discarded transaction
|
||||
completeResults := geth.CompleteTransactions(string(updatedTxIdStrings), testAddressPassword)
|
||||
completeResults := geth.CompleteTransactions(string(updatedTxIdStrings), testConfig.Account1.Password)
|
||||
if len(completeResults) != (testTxCount + 1) {
|
||||
t.Error("unexpected number of errors (call to CompleteTransaction should not succeed)")
|
||||
}
|
||||
|
@ -769,8 +759,8 @@ func TestNonExistentQueuedTransactions(t *testing.T) {
|
|||
}
|
||||
|
||||
// log into account from which transactions will be sent
|
||||
if err := geth.SelectAccount(testAddress, testAddressPassword); err != nil {
|
||||
t.Errorf("cannot select account: %v", testAddress)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -788,11 +778,10 @@ func TestNonExistentQueuedTransactions(t *testing.T) {
|
|||
}
|
||||
if envelope.Type == geth.EventTransactionQueued {
|
||||
event := envelope.Event.(map[string]interface{})
|
||||
t.Logf("Transaction queued (will be completed in 5 secs): {id: %s}\n", event["id"].(string))
|
||||
time.Sleep(5 * time.Second)
|
||||
t.Logf("Transaction queued (will be completed shortly): {id: %s}\n", event["id"].(string))
|
||||
|
||||
// next call is the very same one, but with the correct password
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testAddressPassword); err != nil {
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot complete queued transation[%v]: %v", event["id"], err)
|
||||
return
|
||||
}
|
||||
|
@ -803,7 +792,7 @@ func TestNonExistentQueuedTransactions(t *testing.T) {
|
|||
})
|
||||
|
||||
// try completing non-existing transaction
|
||||
if _, err = geth.CompleteTransaction("some-bad-transaction-id", testAddressPassword); err == nil {
|
||||
if _, err = geth.CompleteTransaction("some-bad-transaction-id", testConfig.Account1.Password); err == nil {
|
||||
t.Error("error expected and not recieved")
|
||||
return
|
||||
}
|
||||
|
@ -829,8 +818,8 @@ func TestEvictionOfQueuedTransactions(t *testing.T) {
|
|||
backend := lightEthereum.StatusBackend
|
||||
|
||||
// log into account from which transactions will be sent
|
||||
if err := geth.SelectAccount(testAddress, testAddressPassword); err != nil {
|
||||
t.Errorf("cannot select account: %v", testAddress)
|
||||
if err := geth.SelectAccount(testConfig.Account1.Address, testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v", testConfig.Account1.Address)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -848,11 +837,10 @@ func TestEvictionOfQueuedTransactions(t *testing.T) {
|
|||
}
|
||||
if envelope.Type == geth.EventTransactionQueued {
|
||||
event := envelope.Event.(map[string]interface{})
|
||||
t.Logf("Transaction queued (will be completed in 5 secs): {id: %s}\n", event["id"].(string))
|
||||
time.Sleep(5 * time.Second)
|
||||
t.Logf("Transaction queued (will be completed shortly): {id: %s}\n", event["id"].(string))
|
||||
|
||||
// next call is the very same one, but with the correct password
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testAddressPassword); err != nil {
|
||||
if txHash, err = geth.CompleteTransaction(event["id"].(string), testConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot complete queued transation[%v]: %v", event["id"], err)
|
||||
return
|
||||
}
|
||||
|
|
102
geth/utils.go
102
geth/utils.go
|
@ -11,8 +11,8 @@ import (
|
|||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
@ -20,17 +20,33 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/logger"
|
||||
"github.com/ethereum/go-ethereum/logger/glog"
|
||||
"github.com/status-im/status-go/geth/params"
|
||||
)
|
||||
|
||||
var muPrepareTestNode sync.Mutex
|
||||
|
||||
const (
|
||||
TestDataDir = "../.ethereumtest"
|
||||
TestNodeSyncSeconds = 60
|
||||
TestNodeHTTPPort = 8645
|
||||
TestNodeWSPort = 8646
|
||||
var (
|
||||
muPrepareTestNode sync.Mutex
|
||||
RootDir string
|
||||
DataDir string
|
||||
TestDataDir string
|
||||
)
|
||||
|
||||
func init() {
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// setup root directory
|
||||
RootDir = filepath.Dir(pwd)
|
||||
if strings.HasSuffix(RootDir, "geth") || strings.HasSuffix(RootDir, "cmd") { // we need to hop one more level
|
||||
RootDir = filepath.Join(RootDir, "..")
|
||||
}
|
||||
|
||||
// setup auxiliary directories
|
||||
DataDir = filepath.Join(RootDir, "data")
|
||||
TestDataDir = filepath.Join(RootDir, ".ethereumtest")
|
||||
}
|
||||
|
||||
type NodeNotificationHandler func(jsonEvent string)
|
||||
|
||||
var notificationHandler NodeNotificationHandler = TriggerDefaultNodeNotificationHandler
|
||||
|
@ -61,6 +77,35 @@ func TriggerTestSignal() {
|
|||
C.StatusServiceSignalEvent(C.CString(`{"answer": 42}`))
|
||||
}
|
||||
|
||||
// TestConfig contains shared (among different test packages) parameters
|
||||
type TestConfig struct {
|
||||
Node struct {
|
||||
SyncSeconds time.Duration
|
||||
HTTPPort int
|
||||
WSPort int
|
||||
}
|
||||
Account1 struct {
|
||||
Address string
|
||||
Password string
|
||||
}
|
||||
Account2 struct {
|
||||
Address string
|
||||
Password string
|
||||
}
|
||||
}
|
||||
|
||||
// LoadTestConfig loads test configuration values from disk
|
||||
func LoadTestConfig() (*TestConfig, error) {
|
||||
var testConfig TestConfig
|
||||
|
||||
configData := LoadFromFile(filepath.Join(DataDir, "test-data.json"))
|
||||
if err := json.Unmarshal([]byte(configData), &testConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &testConfig, nil
|
||||
}
|
||||
|
||||
func CopyFile(dst, src string) error {
|
||||
s, err := os.Open(src)
|
||||
if err != nil {
|
||||
|
@ -106,14 +151,18 @@ func PrepareTestNode() (err error) {
|
|||
|
||||
defer HaltOnPanic()
|
||||
|
||||
testConfig, err := LoadTestConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
syncRequired := false
|
||||
if _, err := os.Stat(filepath.Join(TestDataDir, "testnet")); os.IsNotExist(err) {
|
||||
syncRequired = true
|
||||
}
|
||||
|
||||
// prepare node directory
|
||||
dataDir, err := PreprocessDataDir(TestDataDir)
|
||||
if err != nil {
|
||||
if err := os.MkdirAll(filepath.Join(TestDataDir, "testnet", "keystore"), os.ModePerm); err != nil {
|
||||
glog.V(logger.Warn).Infoln("make node failed:", err)
|
||||
return err
|
||||
}
|
||||
|
@ -121,7 +170,7 @@ func PrepareTestNode() (err error) {
|
|||
// import test account (with test ether on it)
|
||||
dst := filepath.Join(TestDataDir, "testnet", "keystore", "test-account.pk")
|
||||
if _, err := os.Stat(dst); os.IsNotExist(err) {
|
||||
err = CopyFile(dst, filepath.Join("../data", "test-account.pk"))
|
||||
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
|
||||
|
@ -129,14 +178,14 @@ func PrepareTestNode() (err error) {
|
|||
}
|
||||
|
||||
// start geth node and wait for it to initialize
|
||||
err = CreateAndRunNode(&NodeConfig{
|
||||
DataDir: dataDir,
|
||||
IPCEnabled: false,
|
||||
HTTPPort: TestNodeHTTPPort, // to avoid conflicts with running app, using different port in tests
|
||||
WSEnabled: false,
|
||||
WSPort: TestNodeWSPort, // ditto
|
||||
TLSEnabled: false,
|
||||
})
|
||||
config, err := params.NewNodeConfig(TestDataDir, params.TestNetworkId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.HTTPPort = testConfig.Node.HTTPPort // to avoid conflicts with running app, using different port in tests
|
||||
config.WSPort = testConfig.Node.WSPort // ditto
|
||||
|
||||
err = CreateAndRunNode(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -156,8 +205,8 @@ func PrepareTestNode() (err error) {
|
|||
}
|
||||
|
||||
if syncRequired {
|
||||
glog.V(logger.Warn).Infof("Sync is required, it will take %d seconds", TestNodeSyncSeconds)
|
||||
time.Sleep(TestNodeSyncSeconds * time.Second) // LES syncs headers, so that we are up do date when it is done
|
||||
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)
|
||||
}
|
||||
|
@ -172,17 +221,6 @@ func RemoveTestNode() {
|
|||
}
|
||||
}
|
||||
|
||||
func PreprocessDataDir(dataDir string) (string, error) {
|
||||
testDataDir := path.Join(dataDir, "testnet", "keystore")
|
||||
if _, err := os.Stat(testDataDir); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(testDataDir, 0755); err != nil {
|
||||
return dataDir, ErrDataDirPreprocessingFailed
|
||||
}
|
||||
}
|
||||
|
||||
return dataDir, nil
|
||||
}
|
||||
|
||||
// PanicAfter throws panic() after waitSeconds, unless abort channel receives notification
|
||||
func PanicAfter(waitSeconds time.Duration, abort chan struct{}, desc string) {
|
||||
go func() {
|
||||
|
|
|
@ -11,6 +11,14 @@ import (
|
|||
"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) {
|
||||
err := geth.PrepareTestNode()
|
||||
if err != nil {
|
||||
|
@ -35,7 +43,7 @@ func TestWhisperMessaging(t *testing.T) {
|
|||
}
|
||||
|
||||
// create an accounts
|
||||
address1, pubKey1, _, err := geth.CreateAccount(newAccountPassword)
|
||||
address1, pubKey1, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
t.Error("Test failed: could not create account")
|
||||
|
@ -43,7 +51,7 @@ func TestWhisperMessaging(t *testing.T) {
|
|||
}
|
||||
t.Logf("Account created: {address: %s, key: %s}", address1, pubKey1)
|
||||
|
||||
address2, pubKey2, _, err := geth.CreateAccount(newAccountPassword)
|
||||
address2, pubKey2, _, err := geth.CreateAccount(testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
t.Error("Test failed: could not create account")
|
||||
|
@ -72,7 +80,7 @@ func TestWhisperMessaging(t *testing.T) {
|
|||
if whisperService.HasIdentity(crypto.ToECDSAPub(common.FromHex(pubKey1))) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
err = geth.SelectAccount(address1, newAccountPassword)
|
||||
err = geth.SelectAccount(address1, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
|
@ -86,7 +94,7 @@ func TestWhisperMessaging(t *testing.T) {
|
|||
}
|
||||
|
||||
// double selecting (shouldn't be a problem)
|
||||
err = geth.SelectAccount(address1, newAccountPassword)
|
||||
err = geth.SelectAccount(address1, testConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue