Introduced a private Ethereum network for testing purposes (#397)

1. A new private testing network (StatusChain) is introduced.
2. An example test case implemented (TestSendEtherOnStatusChainTx)
3. Genesis file added static/config/status-chain-genesis.json
This commit is contained in:
screwyprof 2017-10-17 00:54:56 +03:00 committed by Ivan Tomilov
parent 240149786f
commit 26fcfda87c
6 changed files with 171 additions and 21 deletions

View File

@ -314,6 +314,87 @@ func (s *TransactionsTestSuite) TestSendEtherTx() {
s.Zero(s.Backend.TxQueueManager().TransactionQueue().Count(), "tx queue must be empty at this point")
}
func (s *TransactionsTestSuite) TestSendEtherOnStatusChainTx() {
s.StartTestBackend(params.StatusChainNetworkID)
defer s.StopTestBackend()
backend := s.LightEthereumService().StatusBackend
s.NotNil(backend)
// create an account
sampleAddress, _, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
s.NoError(err)
completeQueuedTransaction := make(chan struct{})
// replace transaction notification handler
var txHash = gethcommon.Hash{}
signal.SetDefaultNodeNotificationHandler(func(jsonEvent string) { // nolint: dupl
var envelope signal.Envelope
err := json.Unmarshal([]byte(jsonEvent), &envelope)
s.NoError(err, fmt.Sprintf("cannot unmarshal JSON: %s", jsonEvent))
if envelope.Type == txqueue.EventTransactionQueued {
event := envelope.Event.(map[string]interface{})
log.Info("transaction queued (will be completed shortly)", "id", event["id"].(string))
// the first call will fail (we are not logged in, but trying to complete tx)
log.Info("trying to complete with no user logged in")
txHash, err = s.Backend.CompleteTransaction(
common.QueuedTxID(event["id"].(string)),
TestConfig.Account1.Password,
)
s.EqualError(
err,
account.ErrNoAccountSelected.Error(),
fmt.Sprintf("expected error on queued transaction[%v] not thrown", event["id"]),
)
// the second call will also fail (we are logged in as different user)
log.Info("trying to complete with invalid user")
err = s.Backend.AccountManager().SelectAccount(sampleAddress, TestConfig.Account1.Password)
s.NoError(err)
txHash, err = s.Backend.CompleteTransaction(
common.QueuedTxID(event["id"].(string)), TestConfig.Account1.Password)
s.EqualError(
err,
txqueue.ErrInvalidCompleteTxSender.Error(),
fmt.Sprintf("expected error on queued transaction[%v] not thrown", event["id"]),
)
// the third call will work as expected (as we are logged in with correct credentials)
log.Info("trying to complete with correct user, this should succeed")
s.NoError(s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password))
txHash, err = s.Backend.CompleteTransaction(
common.QueuedTxID(event["id"].(string)),
TestConfig.Account1.Password,
)
s.NoError(err, fmt.Sprintf("cannot complete queued transaction[%v]", event["id"]))
close(completeQueuedTransaction)
return
}
})
// this call blocks, up until Complete Transaction is called
txHashCheck, err := s.Backend.SendTransaction(nil, common.SendTxArgs{
From: common.FromAddress(TestConfig.Account1.Address),
To: common.ToAddress(TestConfig.Account2.Address),
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
})
s.NoError(err, "cannot send transaction")
select {
case <-completeQueuedTransaction:
case <-time.After(2 * time.Minute):
s.FailNow("completing transaction timed out")
}
s.Equal(txHashCheck.Hex(), txHash.Hex(), "transaction hash returned from SendTransaction is invalid")
s.False(reflect.DeepEqual(txHashCheck, gethcommon.Hash{}), "transaction was never queued or completed")
s.Zero(s.Backend.TxQueueManager().TransactionQueue().Count(), "tx queue must be empty at this point")
}
func (s *TransactionsTestSuite) TestSendEtherTxUpstream() {
s.StartTestBackend(
params.RopstenNetworkID,

View File

@ -497,6 +497,12 @@ func (c *NodeConfig) updateGenesisConfig() error {
genesis = core.DefaultTestnetGenesisBlock()
case RinkebyNetworkID:
genesis = core.DefaultRinkebyGenesisBlock()
case StatusChainNetworkID:
var err error
genesis, err = c.DefaultStatusChainGenesisBlock()
if err != nil {
return err
}
default:
return nil
}
@ -511,6 +517,20 @@ func (c *NodeConfig) updateGenesisConfig() error {
return nil
}
// DefaultStatusChainGenesisBlock returns the StatusChain network genesis block.
func (c *NodeConfig) DefaultStatusChainGenesisBlock() (*core.Genesis, error) {
genesisJSON, err := static.Asset("config/status-chain-genesis.json")
if err != nil {
return nil, fmt.Errorf("status-chain-genesis.json could not be loaded: %s", err)
}
var genesis *core.Genesis
if err := json.Unmarshal([]byte(genesisJSON), &genesis); err != nil {
return nil, fmt.Errorf("cannot unmarshal status-chain-genesis.json: %s", err)
}
return genesis, nil
}
// updateUpstreamConfig sets the proper UpstreamConfig.URL for the network id being used.
func (c *NodeConfig) updateUpstreamConfig() error {

View File

@ -99,4 +99,7 @@ const (
// RinkebyNetworkID is id of a test network (on PoA)
RinkebyNetworkID = 4
// StatusChainNetworkID is id of a test network (private chain)
StatusChainNetworkID = 777
)

View File

@ -4,6 +4,7 @@
// scripts/web3.js
// config/cht.json
// config/linter_exclude_list.txt
// config/status-chain-genesis.json
// config/test-data.json
// keys/firebaseauthkey
// keys/test-account1-before-eip55.pk
@ -100,7 +101,7 @@ func scriptsReadmeMd() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "scripts/README.md", size: 133, mode: os.FileMode(420), modTime: time.Unix(1498222808, 0)}
info := bindataFileInfo{name: "scripts/README.md", size: 133, mode: os.FileMode(420), modTime: time.Unix(1506194117, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -120,7 +121,7 @@ func scriptsWeb3Js() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "scripts/web3.js", size: 497689, mode: os.FileMode(420), modTime: time.Unix(1507747781, 0)}
info := bindataFileInfo{name: "scripts/web3.js", size: 497689, mode: os.FileMode(420), modTime: time.Unix(1508188203, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -140,7 +141,7 @@ func configChtJson() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "config/cht.json", size: 7624, mode: os.FileMode(420), modTime: time.Unix(1507747773, 0)}
info := bindataFileInfo{name: "config/cht.json", size: 7624, mode: os.FileMode(420), modTime: time.Unix(1507816211, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -160,7 +161,27 @@ func configLinter_exclude_listTxt() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "config/linter_exclude_list.txt", size: 2258, mode: os.FileMode(420), modTime: time.Unix(1498222808, 0)}
info := bindataFileInfo{name: "config/linter_exclude_list.txt", size: 2258, mode: os.FileMode(420), modTime: time.Unix(1506194117, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var _configStatusChainGenesisJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x91\x4b\x8e\xdb\x30\x0c\x86\xf7\x39\x85\xa0\x75\x17\xd4\x83\xa4\xe4\x9d\xed\x38\x68\x81\xee\x7a\x02\x5a\x92\x27\xc6\x38\x71\x90\x38\xc0\x4c\x8b\xb9\x7b\x91\x47\xd3\xa0\xe8\x78\x63\x48\x1f\xf9\x7f\x94\xf4\x6b\xa5\x94\x96\x69\x9a\x93\xae\xd4\x65\xa1\x94\xd2\x75\xae\x07\x83\xd0\x47\xc0\x76\xc0\x8e\x6a\xe6\xd0\x21\xba\xce\x60\x6d\x5c\x6c\x88\x4c\x68\xfa\x86\xff\xb6\x28\xdd\xcb\x24\xfb\x54\x74\xa5\x34\xbc\x19\xd8\x40\xbb\x01\xf2\xeb\x35\x46\x0b\x97\x4f\x5f\x0b\x3f\xbe\x5c\x7f\x9a\xb0\x05\x83\x81\x44\xa0\x2d\x06\x6d\x70\x98\x38\x04\x69\x0b\x11\x96\x68\xea\xde\xa1\xe5\x3e\x7c\x6e\x68\x4c\xdd\xf9\x35\x75\xb6\xdb\xe0\xb3\x60\x75\x97\xe8\x34\xef\x87\xf1\xe5\x11\xa0\xd3\x56\xc6\xfd\xb7\xac\x2b\xc5\xcc\xf7\x31\xb6\xf3\xae\x9c\x96\x22\xb9\x99\xe6\xf4\xaa\x2b\x05\x77\x90\x65\xde\xcc\xc7\xd7\x1f\xe7\xc3\x61\x3e\x2e\xba\x52\xcb\xf1\x5c\xee\xac\x7f\xff\x29\xfb\x65\x3c\xef\xfe\x6d\x2a\xe3\xc1\x20\x7c\x95\xd3\xf6\x36\xa3\x37\xd1\x1b\xb0\x8e\x02\x44\xeb\x0a\x0c\xc5\x67\xf6\xe2\x7c\x9f\x25\x05\xe3\xcd\x60\xd1\x43\x71\x52\x22\x90\x75\x6c\x42\xf1\x9c\x89\xb2\x49\xe2\xc5\x66\xfd\x9c\x8b\xff\xb5\x85\xc7\xee\xe3\xdc\x79\x1c\x86\x31\x9d\xa7\xe5\xfd\xcf\x5b\x5c\x6f\xe7\xca\xca\xdb\x72\x94\xb5\x2c\x72\x43\xe8\xd8\x93\x61\xcf\xc8\xce\x3b\x0a\x64\x28\x52\xb1\x80\xc0\x96\x22\xd3\x85\x11\x5a\x40\x4f\xc8\x97\xda\x48\x85\xd8\x82\x2f\x84\xec\x99\x69\x60\x4b\xfd\x2d\xfa\x45\x4e\xdf\xc7\xdd\xb8\x3c\x4b\x41\xaf\x3e\x56\xbf\x03\x00\x00\xff\xff\xf1\x46\x63\xd8\x62\x02\x00\x00")
func configStatusChainGenesisJsonBytes() ([]byte, error) {
return bindataRead(
_configStatusChainGenesisJson,
"config/status-chain-genesis.json",
)
}
func configStatusChainGenesisJson() (*asset, error) {
bytes, err := configStatusChainGenesisJsonBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "config/status-chain-genesis.json", size: 610, mode: os.FileMode(420), modTime: time.Unix(1508185315, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -180,7 +201,7 @@ func configTestDataJson() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "config/test-data.json", size: 302, mode: os.FileMode(420), modTime: time.Unix(1507747350, 0)}
info := bindataFileInfo{name: "config/test-data.json", size: 302, mode: os.FileMode(420), modTime: time.Unix(1507638424, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -200,7 +221,7 @@ func keysFirebaseauthkey() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "keys/firebaseauthkey", size: 153, mode: os.FileMode(420), modTime: time.Unix(1498222808, 0)}
info := bindataFileInfo{name: "keys/firebaseauthkey", size: 153, mode: os.FileMode(420), modTime: time.Unix(1506194117, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -220,7 +241,7 @@ func keysTestAccount1BeforeEip55Pk() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "keys/test-account1-before-eip55.pk", size: 638, mode: os.FileMode(420), modTime: time.Unix(1507747350, 0)}
info := bindataFileInfo{name: "keys/test-account1-before-eip55.pk", size: 638, mode: os.FileMode(420), modTime: time.Unix(1507638424, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -240,7 +261,7 @@ func keysTestAccount1Pk() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "keys/test-account1.pk", size: 638, mode: os.FileMode(420), modTime: time.Unix(1507747350, 0)}
info := bindataFileInfo{name: "keys/test-account1.pk", size: 638, mode: os.FileMode(420), modTime: time.Unix(1507638424, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -260,7 +281,7 @@ func keysTestAccount2Pk() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "keys/test-account2.pk", size: 1074, mode: os.FileMode(420), modTime: time.Unix(1507747350, 0)}
info := bindataFileInfo{name: "keys/test-account2.pk", size: 1074, mode: os.FileMode(420), modTime: time.Unix(1507638424, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -280,7 +301,7 @@ func keysWnodekey() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "keys/wnodekey", size: 65, mode: os.FileMode(420), modTime: time.Unix(1498222808, 0)}
info := bindataFileInfo{name: "keys/wnodekey", size: 65, mode: os.FileMode(420), modTime: time.Unix(1506194117, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -300,7 +321,7 @@ func keysWnodepassword() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "keys/wnodepassword", size: 9, mode: os.FileMode(420), modTime: time.Unix(1498222808, 0)}
info := bindataFileInfo{name: "keys/wnodepassword", size: 9, mode: os.FileMode(420), modTime: time.Unix(1506194117, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -320,7 +341,7 @@ func testdataJailCommandsJs() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "testdata/jail/commands.js", size: 7677, mode: os.FileMode(420), modTime: time.Unix(1500264813, 0)}
info := bindataFileInfo{name: "testdata/jail/commands.js", size: 7677, mode: os.FileMode(420), modTime: time.Unix(1506194117, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -340,7 +361,7 @@ func testdataJailStatusJs() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "testdata/jail/status.js", size: 3402, mode: os.FileMode(420), modTime: time.Unix(1500264813, 0)}
info := bindataFileInfo{name: "testdata/jail/status.js", size: 3402, mode: os.FileMode(420), modTime: time.Unix(1506194117, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -360,7 +381,7 @@ func testdataJailTxSendContextNoMessageIdJs() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "testdata/jail/tx-send/context-no-message-id.js", size: 1793, mode: os.FileMode(420), modTime: time.Unix(1500821837, 0)}
info := bindataFileInfo{name: "testdata/jail/tx-send/context-no-message-id.js", size: 1793, mode: os.FileMode(420), modTime: time.Unix(1506194117, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -380,7 +401,7 @@ func testdataJailTxSendMessageIdNoContextJs() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "testdata/jail/tx-send/message-id-no-context.js", size: 1875, mode: os.FileMode(420), modTime: time.Unix(1500264813, 0)}
info := bindataFileInfo{name: "testdata/jail/tx-send/message-id-no-context.js", size: 1875, mode: os.FileMode(420), modTime: time.Unix(1506194117, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -400,7 +421,7 @@ func testdataJailTxSendNoMessageIdOrContextJs() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "testdata/jail/tx-send/no-message-id-or-context.js", size: 1354, mode: os.FileMode(420), modTime: time.Unix(1500264813, 0)}
info := bindataFileInfo{name: "testdata/jail/tx-send/no-message-id-or-context.js", size: 1354, mode: os.FileMode(420), modTime: time.Unix(1506194117, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -420,7 +441,7 @@ func testdataJailTxSendTxSendJs() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "testdata/jail/tx-send/tx-send.js", size: 3343, mode: os.FileMode(420), modTime: time.Unix(1507647025, 0)}
info := bindataFileInfo{name: "testdata/jail/tx-send/tx-send.js", size: 3343, mode: os.FileMode(420), modTime: time.Unix(1506194117, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -440,7 +461,7 @@ func testdataNodeTestSol() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "testdata/node/test.sol", size: 119, mode: os.FileMode(420), modTime: time.Unix(1500264813, 0)}
info := bindataFileInfo{name: "testdata/node/test.sol", size: 119, mode: os.FileMode(420), modTime: time.Unix(1506194117, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
@ -501,6 +522,7 @@ var _bindata = map[string]func() (*asset, error){
"scripts/web3.js": scriptsWeb3Js,
"config/cht.json": configChtJson,
"config/linter_exclude_list.txt": configLinter_exclude_listTxt,
"config/status-chain-genesis.json": configStatusChainGenesisJson,
"config/test-data.json": configTestDataJson,
"keys/firebaseauthkey": keysFirebaseauthkey,
"keys/test-account1-before-eip55.pk": keysTestAccount1BeforeEip55Pk,
@ -560,6 +582,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
"config": &bintree{nil, map[string]*bintree{
"cht.json": &bintree{configChtJson, map[string]*bintree{}},
"linter_exclude_list.txt": &bintree{configLinter_exclude_listTxt, map[string]*bintree{}},
"status-chain-genesis.json": &bintree{configStatusChainGenesisJson, map[string]*bintree{}},
"test-data.json": &bintree{configTestDataJson, map[string]*bintree{}},
}},
"keys": &bintree{nil, map[string]*bintree{

View File

@ -0,0 +1,22 @@
{
"alloc": {
"AdAf150b905Cf5E6A778E553E15A139B6618BbB7": {
"balance": "0x10F0CF064DD59200000"
},
"65C01586aa0Ce152835c788aCe665e91Ab3527b8": {
"balance": "0x1B1AE4D6E2EF500000"
}
},
"config": {
"chainId": 777,
"homesteadBlock": 0,
"daoForkSupport": true,
"byzantiumBlock": 0,
"eip150Hash": "0x28c4da1cca48d0107ea5ea29a40ac15fca86899c52d02309fa12ea39b86d219c",
"eip155Block": 0,
"eip158Block": 0
},
"difficulty": "0x100000",
"extraData": "0x537461747573436861696e20507269766174652054657374696e67204e6574776f726b",
"gasLimit": "0x1000000"
}

View File

@ -23,9 +23,10 @@ var (
// TestNetworkNames network ID to name mapping
TestNetworkNames = map[int]string{
params.MainNetworkID: "Mainnet",
params.RopstenNetworkID: "Ropsten",
params.RinkebyNetworkID: "Rinkeby",
params.MainNetworkID: "Mainnet",
params.RopstenNetworkID: "Ropsten",
params.RinkebyNetworkID: "Rinkeby",
params.StatusChainNetworkID: "StatusChain",
}
)