[service][node] Project Tech debt clean up, remove wallet (#2664)
* [project][p2p] Remove wallet, client roles & associated function calls * [node][service] Remove unused service types * [wallet] Remove internal wallet code * [test] Remove wallet from debug.sh * [test] More cleanup in debug.sh, deploy.sh * [test] Adjust duration back into local test script * [test] Increase duration * [test] Exit with 0, remove RESULT_FILE as not made anymorepull/2667/head
parent
afeeb69094
commit
4e85d7d866
@ -1,51 +0,0 @@ |
|||||||
package randomness |
|
||||||
|
|
||||||
import ( |
|
||||||
"github.com/ethereum/go-ethereum/rpc" |
|
||||||
msg_pb "github.com/harmony-one/harmony/api/proto/message" |
|
||||||
"github.com/harmony-one/harmony/drand" |
|
||||||
"github.com/harmony-one/harmony/internal/utils" |
|
||||||
) |
|
||||||
|
|
||||||
// Service is the randomness generation service.
|
|
||||||
type Service struct { |
|
||||||
stopChan chan struct{} |
|
||||||
stoppedChan chan struct{} |
|
||||||
DRand *drand.DRand |
|
||||||
messageChan chan *msg_pb.Message |
|
||||||
} |
|
||||||
|
|
||||||
// New returns randomness generation service.
|
|
||||||
func New(dRand *drand.DRand) *Service { |
|
||||||
return &Service{DRand: dRand} |
|
||||||
} |
|
||||||
|
|
||||||
// StartService starts randomness generation service.
|
|
||||||
func (s *Service) StartService() { |
|
||||||
s.stopChan = make(chan struct{}) |
|
||||||
s.stoppedChan = make(chan struct{}) |
|
||||||
s.DRand.WaitForEpochBlock(s.DRand.ConfirmedBlockChannel, s.stopChan, s.stoppedChan) |
|
||||||
} |
|
||||||
|
|
||||||
// StopService stops randomness generation service.
|
|
||||||
func (s *Service) StopService() { |
|
||||||
utils.Logger().Info().Msg("Stopping random generation service") |
|
||||||
s.stopChan <- struct{}{} |
|
||||||
<-s.stoppedChan |
|
||||||
utils.Logger().Info().Msg("Random generation stopped") |
|
||||||
} |
|
||||||
|
|
||||||
// NotifyService notify service
|
|
||||||
func (s *Service) NotifyService(params map[string]interface{}) { |
|
||||||
return |
|
||||||
} |
|
||||||
|
|
||||||
// SetMessageChan sets up message channel to service.
|
|
||||||
func (s *Service) SetMessageChan(messageChan chan *msg_pb.Message) { |
|
||||||
s.messageChan = messageChan |
|
||||||
} |
|
||||||
|
|
||||||
// APIs for the services.
|
|
||||||
func (s *Service) APIs() []rpc.API { |
|
||||||
return nil |
|
||||||
} |
|
@ -1 +0,0 @@ |
|||||||
The wallet program is the demo wallet which talks to Harmony devnet for various kinds of operations. For detail, please compile and execute ./bin/wallet. |
|
@ -1,84 +0,0 @@ |
|||||||
package main |
|
||||||
|
|
||||||
const ( |
|
||||||
defaultWalletIni = `[main] |
|
||||||
chain_id = 1 |
|
||||||
bootnode = /ip4/100.26.90.187/tcp/9874/p2p/Qmdfjtk6hPoyrH1zVD9PEH4zfWLo38dP2mDvvKXfh3tnEv |
|
||||||
bootnode = /ip4/54.213.43.194/tcp/9874/p2p/QmZJJx6AdaoEkGLrYG4JeLCKeCKDjnFz2wfHNHxAqFSGA9 |
|
||||||
bootnode = /ip4/13.113.101.219/tcp/12019/p2p/QmQayinFSgMMw5cSpDUiD9pQ2WeP6WNmGxpZ6ou3mdVFJX |
|
||||||
bootnode = /ip4/99.81.170.167/tcp/12019/p2p/QmRVbTpEYup8dSaURZfF6ByrMTSKa4UyUzJhSjahFzRqNj |
|
||||||
shards = 4 |
|
||||||
network = mainnet |
|
||||||
|
|
||||||
[main.shard0.rpc] |
|
||||||
rpc = l0.t.hmny.io:14555 |
|
||||||
rpc = s0.t.hmny.io:14555 |
|
||||||
|
|
||||||
[main.shard1.rpc] |
|
||||||
rpc = l1.t.hmny.io:14555 |
|
||||||
rpc = s1.t.hmny.io:14555 |
|
||||||
|
|
||||||
[main.shard2.rpc] |
|
||||||
rpc = l2.t.hmny.io:14555 |
|
||||||
rpc = s2.t.hmny.io:14555 |
|
||||||
|
|
||||||
[main.shard3.rpc] |
|
||||||
rpc = l3.t.hmny.io:14555 |
|
||||||
rpc = s3.t.hmny.io:14555 |
|
||||||
|
|
||||||
[local] |
|
||||||
chain_id = 2 |
|
||||||
bootnode = /ip4/127.0.0.1/tcp/19876/p2p/Qmc1V6W7BwX8Ugb42Ti8RnXF1rY5PF7nnZ6bKBryCgi6cv |
|
||||||
shards = 2 |
|
||||||
network = localnet |
|
||||||
|
|
||||||
[local.shard0.rpc] |
|
||||||
rpc = 127.0.0.1:14555 |
|
||||||
rpc = 127.0.0.1:14557 |
|
||||||
rpc = 127.0.0.1:14559 |
|
||||||
|
|
||||||
[local.shard1.rpc] |
|
||||||
rpc = 127.0.0.1:14556 |
|
||||||
rpc = 127.0.0.1:14558 |
|
||||||
rpc = 127.0.0.1:14560 |
|
||||||
|
|
||||||
[beta] |
|
||||||
chain_id = 2 |
|
||||||
bootnode = /ip4/54.213.43.194/tcp/9868/p2p/QmZJJx6AdaoEkGLrYG4JeLCKeCKDjnFz2wfHNHxAqFSGA9 |
|
||||||
bootnode = /ip4/100.26.90.187/tcp/9868/p2p/Qmdfjtk6hPoyrH1zVD9PEH4zfWLo38dP2mDvvKXfh3tnEv |
|
||||||
bootnode = /ip4/13.113.101.219/tcp/12018/p2p/QmQayinFSgMMw5cSpDUiD9pQ2WeP6WNmGxpZ6ou3mdVFJX |
|
||||||
shards = 2 |
|
||||||
network = testnet |
|
||||||
|
|
||||||
[beta.shard0.rpc] |
|
||||||
rpc = l0.b.hmny.io:14555 |
|
||||||
rpc = s0.b.hmny.io:14555 |
|
||||||
|
|
||||||
[beta.shard1.rpc] |
|
||||||
rpc = l1.b.hmny.io:14555 |
|
||||||
rpc = s1.b.hmny.io:14555 |
|
||||||
|
|
||||||
[pangaea] |
|
||||||
chain_id = 3 |
|
||||||
bootnode = /ip4/54.86.126.90/tcp/9889/p2p/Qmdfjtk6hPoyrH1zVD9PEH4zfWLo38dP2mDvvKXfh3tnEv |
|
||||||
bootnode = /ip4/52.40.84.2/tcp/9889/p2p/QmZJJx6AdaoEkGLrYG4JeLCKeCKDjnFz2wfHNHxAqFSGA9 |
|
||||||
shards = 4 |
|
||||||
network = pangaea |
|
||||||
|
|
||||||
[pangaea.shard0.rpc] |
|
||||||
rpc = l0.p.hmny.io:14555 |
|
||||||
rpc = s0.p.hmny.io:14555 |
|
||||||
|
|
||||||
[pangaea.shard1.rpc] |
|
||||||
rpc = l1.p.hmny.io:14555 |
|
||||||
rpc = s1.p.hmny.io:14555 |
|
||||||
|
|
||||||
[pangaea.shard2.rpc] |
|
||||||
rpc = l2.p.hmny.io:14555 |
|
||||||
rpc = s2.p.hmny.io:14555 |
|
||||||
|
|
||||||
[pangaea.shard3.rpc] |
|
||||||
rpc = l3.p.hmny.io:14555 |
|
||||||
rpc = s3.p.hmny.io:14555 |
|
||||||
` |
|
||||||
) |
|
File diff suppressed because it is too large
Load Diff
@ -1,51 +0,0 @@ |
|||||||
package main |
|
||||||
|
|
||||||
import ( |
|
||||||
"testing" |
|
||||||
|
|
||||||
"github.com/harmony-one/harmony/internal/common" |
|
||||||
) |
|
||||||
|
|
||||||
func TestIsValidAddress(t *testing.T) { |
|
||||||
tests := []struct { |
|
||||||
str string |
|
||||||
exp bool |
|
||||||
}{ |
|
||||||
{"one1ay37rp2pc3kjarg7a322vu3sa8j9puahg679z3", true}, |
|
||||||
{"0x7c41E0668B551f4f902cFaec05B5Bdca68b124CE", true}, |
|
||||||
{"onefoofoo", false}, |
|
||||||
{"0xbarbar", false}, |
|
||||||
{"dsasdadsasaadsas", false}, |
|
||||||
{"32312123213213212321", false}, |
|
||||||
} |
|
||||||
|
|
||||||
for _, test := range tests { |
|
||||||
valid, _ := validateAddress(test.str, common.ParseAddr(test.str), "sender") |
|
||||||
|
|
||||||
if valid != test.exp { |
|
||||||
t.Errorf("validateAddress(\"%s\") returned %v, expected %v", test.str, valid, test.exp) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
func TestIsValidShard(t *testing.T) { |
|
||||||
readProfile("local") |
|
||||||
|
|
||||||
tests := []struct { |
|
||||||
shardID int |
|
||||||
exp bool |
|
||||||
}{ |
|
||||||
{0, true}, |
|
||||||
{1, true}, |
|
||||||
{-1, false}, |
|
||||||
{99, false}, |
|
||||||
} |
|
||||||
|
|
||||||
for _, test := range tests { |
|
||||||
valid := validShard(test.shardID, walletProfile.Shards) |
|
||||||
|
|
||||||
if valid != test.exp { |
|
||||||
t.Errorf("validShard(%d) returned %v, expected %v", test.shardID, valid, test.exp) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1 +0,0 @@ |
|||||||
The wallet program is the demo wallet which talks to Harmony devnet for stress testing transactions operations. For detail, please compile and execute ./bin/wallet_stress test stressTest. |
|
@ -1,84 +0,0 @@ |
|||||||
package main |
|
||||||
|
|
||||||
const ( |
|
||||||
defaultWalletIni = `[main] |
|
||||||
chain_id = 1 |
|
||||||
bootnode = /ip4/100.26.90.187/tcp/9874/p2p/Qmdfjtk6hPoyrH1zVD9PEH4zfWLo38dP2mDvvKXfh3tnEv |
|
||||||
bootnode = /ip4/54.213.43.194/tcp/9874/p2p/QmZJJx6AdaoEkGLrYG4JeLCKeCKDjnFz2wfHNHxAqFSGA9 |
|
||||||
bootnode = /ip4/13.113.101.219/tcp/12019/p2p/QmQayinFSgMMw5cSpDUiD9pQ2WeP6WNmGxpZ6ou3mdVFJX |
|
||||||
bootnode = /ip4/99.81.170.167/tcp/12019/p2p/QmRVbTpEYup8dSaURZfF6ByrMTSKa4UyUzJhSjahFzRqNj |
|
||||||
shards = 4 |
|
||||||
network = mainnet |
|
||||||
|
|
||||||
[main.shard0.rpc] |
|
||||||
rpc = l0.t.hmny.io:14555 |
|
||||||
rpc = s0.t.hmny.io:14555 |
|
||||||
|
|
||||||
[main.shard1.rpc] |
|
||||||
rpc = l1.t.hmny.io:14555 |
|
||||||
rpc = s1.t.hmny.io:14555 |
|
||||||
|
|
||||||
[main.shard2.rpc] |
|
||||||
rpc = l2.t.hmny.io:14555 |
|
||||||
rpc = s2.t.hmny.io:14555 |
|
||||||
|
|
||||||
[main.shard3.rpc] |
|
||||||
rpc = l3.t.hmny.io:14555 |
|
||||||
rpc = s3.t.hmny.io:14555 |
|
||||||
|
|
||||||
[local] |
|
||||||
chain_id = 2 |
|
||||||
bootnode = /ip4/127.0.0.1/tcp/19876/p2p/Qmc1V6W7BwX8Ugb42Ti8RnXF1rY5PF7nnZ6bKBryCgi6cv |
|
||||||
shards = 2 |
|
||||||
network = localnet |
|
||||||
|
|
||||||
[local.shard0.rpc] |
|
||||||
rpc = 127.0.0.1:14555 |
|
||||||
rpc = 127.0.0.1:14557 |
|
||||||
rpc = 127.0.0.1:14559 |
|
||||||
|
|
||||||
[local.shard1.rpc] |
|
||||||
rpc = 127.0.0.1:14556 |
|
||||||
rpc = 127.0.0.1:14558 |
|
||||||
rpc = 127.0.0.1:14560 |
|
||||||
|
|
||||||
[beta] |
|
||||||
chain_id = 2 |
|
||||||
bootnode = /ip4/54.213.43.194/tcp/9868/p2p/QmZJJx6AdaoEkGLrYG4JeLCKeCKDjnFz2wfHNHxAqFSGA9 |
|
||||||
bootnode = /ip4/100.26.90.187/tcp/9868/p2p/Qmdfjtk6hPoyrH1zVD9PEH4zfWLo38dP2mDvvKXfh3tnEv |
|
||||||
bootnode = /ip4/13.113.101.219/tcp/12018/p2p/QmQayinFSgMMw5cSpDUiD9pQ2WeP6WNmGxpZ6ou3mdVFJX |
|
||||||
shards = 2 |
|
||||||
network = testnet |
|
||||||
|
|
||||||
[beta.shard0.rpc] |
|
||||||
rpc = l0.b.hmny.io:14555 |
|
||||||
rpc = s0.b.hmny.io:14555 |
|
||||||
|
|
||||||
[beta.shard1.rpc] |
|
||||||
rpc = l1.b.hmny.io:14555 |
|
||||||
rpc = s1.b.hmny.io:14555 |
|
||||||
|
|
||||||
[pangaea] |
|
||||||
chain_id = 3 |
|
||||||
bootnode = /ip4/54.86.126.90/tcp/9889/p2p/Qmdfjtk6hPoyrH1zVD9PEH4zfWLo38dP2mDvvKXfh3tnEv |
|
||||||
bootnode = /ip4/52.40.84.2/tcp/9889/p2p/QmZJJx6AdaoEkGLrYG4JeLCKeCKDjnFz2wfHNHxAqFSGA9 |
|
||||||
shards = 4 |
|
||||||
network = pangaea |
|
||||||
|
|
||||||
[pangaea.shard0.rpc] |
|
||||||
rpc = l0.p.hmny.io:14555 |
|
||||||
rpc = s0.p.hmny.io:14555 |
|
||||||
|
|
||||||
[pangaea.shard1.rpc] |
|
||||||
rpc = l1.p.hmny.io:14555 |
|
||||||
rpc = s1.p.hmny.io:14555 |
|
||||||
|
|
||||||
[pangaea.shard2.rpc] |
|
||||||
rpc = l2.p.hmny.io:14555 |
|
||||||
rpc = s2.p.hmny.io:14555 |
|
||||||
|
|
||||||
[pangaea.shard3.rpc] |
|
||||||
rpc = l3.p.hmny.io:14555 |
|
||||||
rpc = s3.p.hmny.io:14555 |
|
||||||
` |
|
||||||
) |
|
@ -1,474 +0,0 @@ |
|||||||
package main |
|
||||||
|
|
||||||
import ( |
|
||||||
"flag" |
|
||||||
"fmt" |
|
||||||
"io/ioutil" |
|
||||||
"math/big" |
|
||||||
"math/rand" |
|
||||||
"os" |
|
||||||
"path" |
|
||||||
"sync" |
|
||||||
"time" |
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common" |
|
||||||
"github.com/ethereum/go-ethereum/log" |
|
||||||
|
|
||||||
"github.com/harmony-one/harmony/accounts" |
|
||||||
"github.com/harmony-one/harmony/accounts/keystore" |
|
||||||
"github.com/harmony-one/harmony/api/client" |
|
||||||
clientService "github.com/harmony-one/harmony/api/client/service" |
|
||||||
proto_node "github.com/harmony-one/harmony/api/proto/node" |
|
||||||
"github.com/harmony-one/harmony/common/denominations" |
|
||||||
"github.com/harmony-one/harmony/core" |
|
||||||
"github.com/harmony-one/harmony/core/types" |
|
||||||
common2 "github.com/harmony-one/harmony/internal/common" |
|
||||||
nodeconfig "github.com/harmony-one/harmony/internal/configs/node" |
|
||||||
"github.com/harmony-one/harmony/internal/ctxerror" |
|
||||||
"github.com/harmony-one/harmony/internal/shardchain" |
|
||||||
"github.com/harmony-one/harmony/internal/utils" |
|
||||||
"github.com/harmony-one/harmony/internal/wallet" |
|
||||||
"github.com/harmony-one/harmony/node" |
|
||||||
"github.com/harmony-one/harmony/p2p" |
|
||||||
p2p_host "github.com/harmony-one/harmony/p2p/host" |
|
||||||
"github.com/harmony-one/harmony/p2p/p2pimpl" |
|
||||||
p2putils "github.com/harmony-one/harmony/p2p/utils" |
|
||||||
) |
|
||||||
|
|
||||||
var ( |
|
||||||
version string |
|
||||||
builtBy string |
|
||||||
builtAt string |
|
||||||
commit string |
|
||||||
nextNonce uint64 |
|
||||||
) |
|
||||||
|
|
||||||
func printVersion(me string) { |
|
||||||
fmt.Fprintf(os.Stderr, "Harmony (C) 2019. %v, version %v-%v (%v %v)\n", path.Base(me), version, commit, builtBy, builtAt) |
|
||||||
os.Exit(0) |
|
||||||
} |
|
||||||
|
|
||||||
// AccountState includes the balance and nonce of an account
|
|
||||||
type AccountState struct { |
|
||||||
balance *big.Int |
|
||||||
nonce uint64 |
|
||||||
} |
|
||||||
|
|
||||||
const ( |
|
||||||
rpcRetry = 3 |
|
||||||
defaultConfigFile = ".hmy/wallet.ini" |
|
||||||
defaultProfile = "default" |
|
||||||
keystoreDir = ".hmy/keystore" |
|
||||||
) |
|
||||||
|
|
||||||
var ( |
|
||||||
// Transfer subcommands
|
|
||||||
transferCommand = flag.NewFlagSet("transfer", flag.ExitOnError) |
|
||||||
transferSenderPtr = transferCommand.String("from", "0", "Specify the sender account address or index") |
|
||||||
transferReceiverPtr = transferCommand.String("to", "", "Specify the receiver account") |
|
||||||
transferAmountPtr = transferCommand.Float64("amount", 0, "Specify the amount to transfer") |
|
||||||
transferGasPricePtr = transferCommand.Uint64("gasPrice", 0, "Specify the gas price amount. Unit is Nano.") |
|
||||||
transferShardIDPtr = transferCommand.Int("shardID", 0, "Specify the shard ID for the transfer") |
|
||||||
transferInputDataPtr = transferCommand.String("inputData", "", "Base64-encoded input data to embed in the transaction") |
|
||||||
transferSenderPassPtr = transferCommand.String("pass", "", "Passphrase of the sender's private key") |
|
||||||
) |
|
||||||
|
|
||||||
var ( |
|
||||||
walletProfile *wallet.Profile |
|
||||||
ks *keystore.KeyStore |
|
||||||
) |
|
||||||
|
|
||||||
// setupLog setup log for verbose output
|
|
||||||
func setupLog() { |
|
||||||
// enable logging for wallet
|
|
||||||
h := log.StreamHandler(os.Stdout, log.TerminalFormat(true)) |
|
||||||
log.Root().SetHandler(h) |
|
||||||
} |
|
||||||
|
|
||||||
// The main wallet program entrance. Note the this wallet program is for demo-purpose only. It does not implement
|
|
||||||
// the secure storage of keys.
|
|
||||||
func main() { |
|
||||||
rand.Seed(int64(time.Now().Nanosecond())) |
|
||||||
|
|
||||||
// Verify that a subcommand has been provided
|
|
||||||
// os.Arg[0] is the main command
|
|
||||||
// os.Arg[1] will be the subcommand
|
|
||||||
if len(os.Args) < 2 { |
|
||||||
fmt.Println("Usage:") |
|
||||||
fmt.Println(" wallet -p profile <action> <params>") |
|
||||||
fmt.Println(" -p profile - Specify the profile of the wallet, either testnet/devnet or others configured. Default is: testnet") |
|
||||||
fmt.Println(" The profile is in file:", defaultConfigFile) |
|
||||||
fmt.Println() |
|
||||||
fmt.Println("Actions:") |
|
||||||
fmt.Println(" 1. stressTest - Stress test transactions with corner cases.") |
|
||||||
os.Exit(1) |
|
||||||
} |
|
||||||
|
|
||||||
ARG: |
|
||||||
for { |
|
||||||
lastArg := os.Args[len(os.Args)-1] |
|
||||||
switch lastArg { |
|
||||||
case "--verbose": |
|
||||||
setupLog() |
|
||||||
os.Args = os.Args[:len(os.Args)-1] |
|
||||||
default: |
|
||||||
break ARG |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
var profile string |
|
||||||
if os.Args[1] == "-p" { |
|
||||||
profile = os.Args[2] |
|
||||||
os.Args = os.Args[2:] |
|
||||||
} else { |
|
||||||
profile = defaultProfile |
|
||||||
} |
|
||||||
if len(os.Args) == 1 { |
|
||||||
fmt.Println("Missing action") |
|
||||||
flag.PrintDefaults() |
|
||||||
os.Exit(1) |
|
||||||
} |
|
||||||
|
|
||||||
// create new keystore backend
|
|
||||||
scryptN := keystore.StandardScryptN |
|
||||||
scryptP := keystore.StandardScryptP |
|
||||||
ks = keystore.NewKeyStore(keystoreDir, scryptN, scryptP) |
|
||||||
|
|
||||||
// Switch on the subcommand
|
|
||||||
switch os.Args[1] { |
|
||||||
case "-version": |
|
||||||
printVersion(os.Args[0]) |
|
||||||
case "stressTest": |
|
||||||
readProfile(profile) |
|
||||||
processStressTestCommand() |
|
||||||
default: |
|
||||||
fmt.Printf("Unknown action: %s\n", os.Args[1]) |
|
||||||
flag.PrintDefaults() |
|
||||||
os.Exit(1) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
//go:generate go run ../../../scripts/wallet_embed_ini_files.go
|
|
||||||
|
|
||||||
func readProfile(profile string) { |
|
||||||
fmt.Printf("Using %s profile for wallet\n", profile) |
|
||||||
|
|
||||||
// try to load .hmy/wallet.ini from filesystem
|
|
||||||
// use default_wallet_ini if .hmy/wallet.ini doesn't exist
|
|
||||||
var err error |
|
||||||
var iniBytes []byte |
|
||||||
|
|
||||||
iniBytes, err = ioutil.ReadFile(defaultConfigFile) |
|
||||||
if err != nil { |
|
||||||
log.Debug(fmt.Sprintf("%s doesn't exist, using default ini\n", defaultConfigFile)) |
|
||||||
iniBytes = []byte(defaultWalletIni) |
|
||||||
} |
|
||||||
|
|
||||||
walletProfile, err = wallet.ReadProfile(iniBytes, profile) |
|
||||||
if err != nil { |
|
||||||
fmt.Printf("Read wallet profile error: %v\nExiting ...\n", err) |
|
||||||
os.Exit(2) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// createWalletNode creates wallet server node.
|
|
||||||
func createWalletNode() *node.Node { |
|
||||||
bootNodeAddrs, err := p2putils.StringsToAddrs(walletProfile.Bootnodes) |
|
||||||
if err != nil { |
|
||||||
utils.FatalErrMsg(err, "cannot parse bootnodes %#v", walletProfile.Bootnodes) |
|
||||||
} |
|
||||||
p2putils.BootNodes = bootNodeAddrs |
|
||||||
shardID := 0 |
|
||||||
// dummy host for wallet
|
|
||||||
// TODO: potentially, too many dummy IP may flush out good IP address from our bootnode DHT
|
|
||||||
// we need to understand the impact to bootnode DHT with this dummy host ip added
|
|
||||||
self := p2p.Peer{IP: "127.0.0.1", Port: "6999"} |
|
||||||
priKey, _, _ := utils.GenKeyP2P("127.0.0.1", "6999") |
|
||||||
host, err := p2pimpl.NewHost(&self, priKey) |
|
||||||
if err != nil { |
|
||||||
utils.FatalErrMsg(err, "cannot initialize network") |
|
||||||
} |
|
||||||
chainDBFactory := &shardchain.MemDBFactory{} |
|
||||||
w := node.New(host, nil, chainDBFactory, nil, false) |
|
||||||
w.Client = client.NewClient(w.GetHost(), uint32(shardID)) |
|
||||||
|
|
||||||
w.NodeConfig.SetRole(nodeconfig.ClientNode) |
|
||||||
w.ServiceManagerSetup() |
|
||||||
w.RunServices() |
|
||||||
return w |
|
||||||
} |
|
||||||
|
|
||||||
// ./bin/wallet -p local transfer
|
|
||||||
// --from one1uyshu2jgv8w465yc8kkny36thlt2wvel89tcmg
|
|
||||||
// --to one1spshr72utf6rwxseaz339j09ed8p6f8ke370zj
|
|
||||||
// --amount 1 --shardID 1
|
|
||||||
|
|
||||||
func processStressTestCommand() { |
|
||||||
/* |
|
||||||
|
|
||||||
Account 17: |
|
||||||
Address: one1spshr72utf6rwxseaz339j09ed8p6f8ke370zj |
|
||||||
Balance in Shard 0: x.xxx, nonce: 0 |
|
||||||
Balance in Shard 1: 0.0000, nonce: 0 |
|
||||||
Account 18: |
|
||||||
Address: one1uyshu2jgv8w465yc8kkny36thlt2wvel89tcmg |
|
||||||
Balance in Shard 0: 0.0000, nonce: 0 |
|
||||||
Balance in Shard 1: x.xxx, nonce: 0 |
|
||||||
|
|
||||||
*/ |
|
||||||
|
|
||||||
chainID, ok := new(big.Int).SetString(walletProfile.ChainID, 0) |
|
||||||
if !ok { |
|
||||||
fmt.Printf("invalid chain ID %#v in config", walletProfile.ChainID) |
|
||||||
return |
|
||||||
} |
|
||||||
|
|
||||||
fmt.Println("Creating wallet node") |
|
||||||
walletNode := createWalletNode() |
|
||||||
|
|
||||||
senderAddress := common2.ParseAddr("one1uyshu2jgv8w465yc8kkny36thlt2wvel89tcmg") |
|
||||||
receiverAddress := common2.ParseAddr("one1spshr72utf6rwxseaz339j09ed8p6f8ke370zj") |
|
||||||
shardID := 1 |
|
||||||
|
|
||||||
fmt.Printf("Sender account: %s:\n", common2.MustAddressToBech32(senderAddress)) |
|
||||||
|
|
||||||
// default inputData
|
|
||||||
data := make([]byte, 0) |
|
||||||
|
|
||||||
gasLimit, _ := core.IntrinsicGas(data, false, true, false) |
|
||||||
|
|
||||||
gasPrice := 0 |
|
||||||
gasPriceBigInt := big.NewInt(int64(gasPrice)) |
|
||||||
gasPriceBigInt = gasPriceBigInt.Mul(gasPriceBigInt, big.NewInt(denominations.Nano)) |
|
||||||
|
|
||||||
fmt.Printf("gas limit: %d, gas price: %d", gasLimit, gasPriceBigInt.Uint64()) |
|
||||||
|
|
||||||
senderPass := "" |
|
||||||
|
|
||||||
var shardIDToAccountStateSender []*AccountState |
|
||||||
var shardIDToAccountStateReceiver []*AccountState |
|
||||||
var senderState *AccountState |
|
||||||
var receiverState *AccountState |
|
||||||
var retry uint32 |
|
||||||
|
|
||||||
for i := 0; ; i++ { |
|
||||||
for retry = 0; retry < 10; retry++ { |
|
||||||
shardIDToAccountStateSender = FetchBalance(senderAddress) |
|
||||||
shardIDToAccountStateReceiver = FetchBalance(receiverAddress) |
|
||||||
|
|
||||||
senderState = shardIDToAccountStateSender[shardID] |
|
||||||
receiverState = shardIDToAccountStateReceiver[shardID] |
|
||||||
|
|
||||||
if senderState.nonce == nextNonce { |
|
||||||
break |
|
||||||
} |
|
||||||
time.Sleep(3 * time.Second) |
|
||||||
fmt.Printf(".") |
|
||||||
} |
|
||||||
|
|
||||||
if retry == 10 { |
|
||||||
fmt.Printf("\nRetry expired. Num txs made: %d\n", i) |
|
||||||
break |
|
||||||
} |
|
||||||
|
|
||||||
nextNonce++ |
|
||||||
|
|
||||||
senderBalance := senderState.balance |
|
||||||
receiverBalance := receiverState.balance |
|
||||||
|
|
||||||
// amount 1/10th of the balance
|
|
||||||
amountBigInt := senderBalance.Div(senderBalance, big.NewInt(10)) |
|
||||||
|
|
||||||
fmt.Printf("\nsender: balance (shard %d: %s, nonce: %v)\n", shardID, convertBalanceIntoReadableFormat(senderBalance), senderState.nonce) |
|
||||||
fmt.Printf("receiver balance (shard %d: %s, nonce: %v)\n", shardID, convertBalanceIntoReadableFormat(receiverBalance), receiverState.nonce) |
|
||||||
|
|
||||||
// stop stress testing here after printing out the final balance
|
|
||||||
if i == 10 { |
|
||||||
break |
|
||||||
} |
|
||||||
|
|
||||||
tx := types.NewTransaction( |
|
||||||
senderState.nonce, receiverAddress, uint32(shardID), amountBigInt, |
|
||||||
gasLimit, gasPriceBigInt, data) |
|
||||||
|
|
||||||
account, _ := ks.Find(accounts.Account{Address: senderAddress}) |
|
||||||
|
|
||||||
ks.Unlock(account, senderPass) |
|
||||||
|
|
||||||
tx, _ = ks.SignTx(account, tx, chainID) |
|
||||||
|
|
||||||
if err := submitTransaction(tx, walletNode, uint32(shardID)); err != nil { |
|
||||||
fmt.Println(ctxerror.New("submitTransaction failed", |
|
||||||
"tx", tx, "shardID", shardID).WithCause(err)) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
for shardID, balanceNonce := range FetchBalance(senderAddress) { |
|
||||||
fmt.Printf(" Final: Balance in Shard %d: %s, nonce: %v \n", shardID, convertBalanceIntoReadableFormat(balanceNonce.balance), balanceNonce.nonce) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
func convertBalanceIntoReadableFormat(balance *big.Int) string { |
|
||||||
balance = balance.Div(balance, big.NewInt(denominations.Nano)) |
|
||||||
strBalance := fmt.Sprintf("%d", balance.Uint64()) |
|
||||||
|
|
||||||
bytes := []byte(strBalance) |
|
||||||
hasDecimal := false |
|
||||||
for i := 0; i < 11; i++ { |
|
||||||
if len(bytes)-1-i < 0 { |
|
||||||
bytes = append([]byte{'0'}, bytes...) |
|
||||||
} |
|
||||||
if bytes[len(bytes)-1-i] != '0' && i < 9 { |
|
||||||
hasDecimal = true |
|
||||||
} |
|
||||||
if i == 9 { |
|
||||||
newBytes := append([]byte{'.'}, bytes[len(bytes)-i:]...) |
|
||||||
bytes = append(bytes[:len(bytes)-i], newBytes...) |
|
||||||
} |
|
||||||
} |
|
||||||
zerosToRemove := 0 |
|
||||||
for i := 0; i < len(bytes); i++ { |
|
||||||
if hasDecimal { |
|
||||||
if bytes[len(bytes)-1-i] == '0' { |
|
||||||
bytes = bytes[:len(bytes)-1-i] |
|
||||||
i-- |
|
||||||
} else { |
|
||||||
break |
|
||||||
} |
|
||||||
} else { |
|
||||||
if zerosToRemove < 5 { |
|
||||||
bytes = bytes[:len(bytes)-1-i] |
|
||||||
i-- |
|
||||||
zerosToRemove++ |
|
||||||
} else { |
|
||||||
break |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return string(bytes) |
|
||||||
} |
|
||||||
|
|
||||||
// FetchBalance fetches account balance of specified address from the Harmony network
|
|
||||||
func FetchBalance(address common.Address) []*AccountState { |
|
||||||
result := []*AccountState{} |
|
||||||
for shardID := 0; shardID < walletProfile.Shards; shardID++ { |
|
||||||
// Fill in nil pointers for each shard; nil represent failed balance fetch.
|
|
||||||
result = append(result, nil) |
|
||||||
} |
|
||||||
|
|
||||||
var wg sync.WaitGroup |
|
||||||
wg.Add(walletProfile.Shards) |
|
||||||
|
|
||||||
for shardID := 0; shardID < walletProfile.Shards; shardID++ { |
|
||||||
go func(shardID int) { |
|
||||||
defer wg.Done() |
|
||||||
balance := big.NewInt(0) |
|
||||||
var nonce uint64 |
|
||||||
result[uint32(shardID)] = &AccountState{balance, 0} |
|
||||||
|
|
||||||
var wgShard sync.WaitGroup |
|
||||||
wgShard.Add(len(walletProfile.RPCServer[shardID])) |
|
||||||
|
|
||||||
var mutexAccountState = &sync.Mutex{} |
|
||||||
|
|
||||||
for rpcServerID := 0; rpcServerID < len(walletProfile.RPCServer[shardID]); rpcServerID++ { |
|
||||||
go func(rpcServerID int) { |
|
||||||
for retry := 0; retry < rpcRetry; retry++ { |
|
||||||
|
|
||||||
server := walletProfile.RPCServer[shardID][rpcServerID] |
|
||||||
client, err := clientService.NewClient(server.IP, server.Port) |
|
||||||
if err != nil { |
|
||||||
continue |
|
||||||
} |
|
||||||
|
|
||||||
log.Debug("FetchBalance", "server", server) |
|
||||||
response, err := client.GetBalance(address) |
|
||||||
if err != nil { |
|
||||||
log.Info("failed to get balance, retrying ...") |
|
||||||
time.Sleep(200 * time.Millisecond) |
|
||||||
continue |
|
||||||
} |
|
||||||
log.Debug("FetchBalance", "response", response) |
|
||||||
respBalance := big.NewInt(0) |
|
||||||
respBalance.SetBytes(response.Balance) |
|
||||||
|
|
||||||
mutexAccountState.Lock() |
|
||||||
if balance.Cmp(respBalance) < 0 { |
|
||||||
balance.SetBytes(response.Balance) |
|
||||||
nonce = response.Nonce |
|
||||||
} |
|
||||||
mutexAccountState.Unlock() |
|
||||||
break |
|
||||||
} |
|
||||||
wgShard.Done() |
|
||||||
}(rpcServerID) |
|
||||||
} |
|
||||||
wgShard.Wait() |
|
||||||
|
|
||||||
result[shardID] = &AccountState{balance, nonce} |
|
||||||
}(shardID) |
|
||||||
} |
|
||||||
wg.Wait() |
|
||||||
return result |
|
||||||
} |
|
||||||
|
|
||||||
// GetFreeToken requests for token test token on each shard
|
|
||||||
func GetFreeToken(address common.Address) { |
|
||||||
for i := 0; i < walletProfile.Shards; i++ { |
|
||||||
// use the 1st server (leader) to make the getFreeToken call
|
|
||||||
server := walletProfile.RPCServer[i][0] |
|
||||||
client, err := clientService.NewClient(server.IP, server.Port) |
|
||||||
if err != nil { |
|
||||||
continue |
|
||||||
} |
|
||||||
|
|
||||||
log.Debug("GetFreeToken", "server", server) |
|
||||||
|
|
||||||
for retry := 0; retry < rpcRetry; retry++ { |
|
||||||
response, err := client.GetFreeToken(address) |
|
||||||
if err != nil { |
|
||||||
log.Info("failed to get free token, retrying ...") |
|
||||||
time.Sleep(200 * time.Millisecond) |
|
||||||
continue |
|
||||||
} |
|
||||||
log.Debug("GetFreeToken", "response", response) |
|
||||||
txID := common.Hash{} |
|
||||||
txID.SetBytes(response.TxId) |
|
||||||
fmt.Printf("Transaction Id requesting free token in shard %d: %s\n", i, txID.Hex()) |
|
||||||
break |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// clearKeystore deletes all data in the local keystore
|
|
||||||
func clearKeystore() { |
|
||||||
dir, err := ioutil.ReadDir(keystoreDir) |
|
||||||
if err != nil { |
|
||||||
utils.FatalErrMsg(err, "cannot read keystore directory %s", keystoreDir) |
|
||||||
} |
|
||||||
for _, d := range dir { |
|
||||||
subdir := path.Join([]string{keystoreDir, d.Name()}...) |
|
||||||
if err := os.RemoveAll(subdir); err != nil { |
|
||||||
fmt.Println(ctxerror.New("cannot remove directory", |
|
||||||
"path", subdir).WithCause(err)) |
|
||||||
} |
|
||||||
} |
|
||||||
fmt.Println("All existing accounts deleted...") |
|
||||||
} |
|
||||||
|
|
||||||
// submitTransaction submits the transaction to the Harmony network
|
|
||||||
func submitTransaction(tx *types.Transaction, walletNode *node.Node, shardID uint32) error { |
|
||||||
msg := proto_node.ConstructTransactionListMessageAccount(types.Transactions{tx}) |
|
||||||
clientGroup := nodeconfig.NewClientGroupIDByShardID(nodeconfig.ShardID(shardID)) |
|
||||||
|
|
||||||
err := walletNode.GetHost().SendMessageToGroups([]nodeconfig.GroupID{clientGroup}, p2p_host.ConstructP2pMessage(byte(0), msg)) |
|
||||||
if err != nil { |
|
||||||
fmt.Printf("Error in SubmitTransaction: %v\n", err) |
|
||||||
return err |
|
||||||
} |
|
||||||
fmt.Printf("Transaction Id for shard %d: %s\n", int(shardID), tx.Hash().Hex()) |
|
||||||
// FIXME (leo): how to we know the tx was successful sent to the network
|
|
||||||
// this is a hacky way to wait for sometime
|
|
||||||
time.Sleep(3 * time.Second) |
|
||||||
return nil |
|
||||||
} |
|
@ -1,100 +0,0 @@ |
|||||||
package wallet |
|
||||||
|
|
||||||
// this module in utils handles the ini file read/write
|
|
||||||
import ( |
|
||||||
"fmt" |
|
||||||
"os" |
|
||||||
"strings" |
|
||||||
|
|
||||||
ini "gopkg.in/ini.v1" |
|
||||||
|
|
||||||
"github.com/harmony-one/harmony/internal/params" |
|
||||||
"github.com/harmony-one/harmony/p2p" |
|
||||||
) |
|
||||||
|
|
||||||
// Profile contains a section and key value pair map
|
|
||||||
type Profile struct { |
|
||||||
Profile string |
|
||||||
ChainID string |
|
||||||
Bootnodes []string |
|
||||||
Shards int |
|
||||||
RPCServer [][]p2p.Peer |
|
||||||
Network string |
|
||||||
} |
|
||||||
|
|
||||||
// ReadProfile reads an ini file and return Profile
|
|
||||||
func ReadProfile(iniBytes []byte, profile string) (*Profile, error) { |
|
||||||
cfg, err := ini.ShadowLoad(iniBytes) |
|
||||||
if err != nil { |
|
||||||
return nil, err |
|
||||||
} |
|
||||||
config := new(Profile) |
|
||||||
config.Profile = profile |
|
||||||
|
|
||||||
// get the profile section
|
|
||||||
sec, err := cfg.GetSection(profile) |
|
||||||
if err != nil { |
|
||||||
return nil, err |
|
||||||
} |
|
||||||
profile = sec.Name() // sanitized name
|
|
||||||
|
|
||||||
if sec.HasKey("bootnode") { |
|
||||||
config.Bootnodes = sec.Key("bootnode").ValueWithShadows() |
|
||||||
} else { |
|
||||||
return nil, fmt.Errorf("can't find bootnode key") |
|
||||||
} |
|
||||||
if sec.HasKey("network") { |
|
||||||
config.Network = sec.Key("network").String() |
|
||||||
} else { |
|
||||||
config.Network = "devnet" |
|
||||||
} |
|
||||||
if sec.HasKey("chain_id") { |
|
||||||
config.ChainID = sec.Key("chain_id").String() |
|
||||||
} else { |
|
||||||
// backward compatibility; use profile name to determine
|
|
||||||
// (deprecated; require chain_id after 2010-01).
|
|
||||||
switch profile { |
|
||||||
case "main", "default": |
|
||||||
config.ChainID = params.MainnetChainID.String() |
|
||||||
case "pangaea": |
|
||||||
config.ChainID = params.PangaeaChainID.String() |
|
||||||
case "partner": |
|
||||||
config.ChainID = params.PartnerChainID.String() |
|
||||||
case "stressnet": |
|
||||||
config.ChainID = params.StressnetChainID.String() |
|
||||||
default: |
|
||||||
config.ChainID = params.TestnetChainID.String() |
|
||||||
} |
|
||||||
_, _ = fmt.Fprintf(os.Stderr, |
|
||||||
"NOTICE: Chain ID not found in config profile, assuming %s; "+ |
|
||||||
"please add \"chain_id = %s\" to section [%s] of wallet.ini "+ |
|
||||||
"before 2020-01\n", |
|
||||||
config.ChainID, config.ChainID, profile) |
|
||||||
} |
|
||||||
|
|
||||||
if sec.HasKey("shards") { |
|
||||||
config.Shards = sec.Key("shards").MustInt() |
|
||||||
config.RPCServer = make([][]p2p.Peer, config.Shards) |
|
||||||
} else { |
|
||||||
return nil, fmt.Errorf("can't find shards key") |
|
||||||
} |
|
||||||
|
|
||||||
for i := 0; i < config.Shards; i++ { |
|
||||||
rpcSec, err := cfg.GetSection(fmt.Sprintf("%s.shard%v.rpc", profile, i)) |
|
||||||
if err != nil { |
|
||||||
return nil, err |
|
||||||
} |
|
||||||
rpcKey := rpcSec.Key("rpc").ValueWithShadows() |
|
||||||
for _, key := range rpcKey { |
|
||||||
v := strings.Split(key, ":") |
|
||||||
rpc := p2p.Peer{ |
|
||||||
IP: v[0], |
|
||||||
Port: v[1], |
|
||||||
} |
|
||||||
config.RPCServer[i] = append(config.RPCServer[i], rpc) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return config, nil |
|
||||||
|
|
||||||
} |
|
@ -1,123 +0,0 @@ |
|||||||
package wallet |
|
||||||
|
|
||||||
import ( |
|
||||||
"io/ioutil" |
|
||||||
"reflect" |
|
||||||
"testing" |
|
||||||
|
|
||||||
"github.com/harmony-one/harmony/internal/params" |
|
||||||
"github.com/harmony-one/harmony/p2p" |
|
||||||
) |
|
||||||
|
|
||||||
func TestReadWalletProfile(t *testing.T) { |
|
||||||
config := []*Profile{ |
|
||||||
{ |
|
||||||
Profile: "default", |
|
||||||
ChainID: params.MainnetChainID.String(), |
|
||||||
Bootnodes: []string{"127.0.0.1:9000/abcd", "127.0.0.1:9999/daeg"}, |
|
||||||
Shards: 4, |
|
||||||
Network: "mainnet", |
|
||||||
RPCServer: [][]p2p.Peer{ |
|
||||||
{ |
|
||||||
{ |
|
||||||
IP: "127.0.0.4", |
|
||||||
Port: "8888", |
|
||||||
}, |
|
||||||
{ |
|
||||||
IP: "192.168.0.4", |
|
||||||
Port: "9876", |
|
||||||
}, |
|
||||||
}, |
|
||||||
{ |
|
||||||
{ |
|
||||||
IP: "127.0.0.1", |
|
||||||
Port: "8888", |
|
||||||
}, |
|
||||||
{ |
|
||||||
IP: "192.168.0.1", |
|
||||||
Port: "9876", |
|
||||||
}, |
|
||||||
}, |
|
||||||
{ |
|
||||||
{ |
|
||||||
IP: "127.0.0.2", |
|
||||||
Port: "8888", |
|
||||||
}, |
|
||||||
{ |
|
||||||
IP: "192.168.0.2", |
|
||||||
Port: "9876", |
|
||||||
}, |
|
||||||
}, |
|
||||||
{ |
|
||||||
{ |
|
||||||
IP: "127.0.0.3", |
|
||||||
Port: "8888", |
|
||||||
}, |
|
||||||
{ |
|
||||||
IP: "192.168.0.3", |
|
||||||
Port: "9876", |
|
||||||
}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
{ |
|
||||||
Profile: "testnet", |
|
||||||
ChainID: params.TestnetChainID.String(), |
|
||||||
Bootnodes: []string{"192.168.0.1:9990/abcd", "127.0.0.1:8888/daeg"}, |
|
||||||
Shards: 3, |
|
||||||
Network: "testnet", |
|
||||||
RPCServer: [][]p2p.Peer{ |
|
||||||
{ |
|
||||||
{ |
|
||||||
IP: "192.168.2.3", |
|
||||||
Port: "8888", |
|
||||||
}, |
|
||||||
{ |
|
||||||
IP: "192.168.192.3", |
|
||||||
Port: "9877", |
|
||||||
}, |
|
||||||
}, |
|
||||||
{ |
|
||||||
{ |
|
||||||
IP: "192.168.2.1", |
|
||||||
Port: "8888", |
|
||||||
}, |
|
||||||
{ |
|
||||||
IP: "192.168.192.1", |
|
||||||
Port: "9877", |
|
||||||
}, |
|
||||||
}, |
|
||||||
{ |
|
||||||
{ |
|
||||||
IP: "192.168.2.2", |
|
||||||
Port: "8888", |
|
||||||
}, |
|
||||||
{ |
|
||||||
IP: "192.168.192.2", |
|
||||||
Port: "9877", |
|
||||||
}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
} |
|
||||||
|
|
||||||
testIniBytes, err := ioutil.ReadFile("test.ini") |
|
||||||
if err != nil { |
|
||||||
t.Fatalf("Failed to read test.ini: %v", err) |
|
||||||
} |
|
||||||
|
|
||||||
config1, err := ReadProfile(testIniBytes, "default") |
|
||||||
if err != nil { |
|
||||||
t.Fatalf("ReadProfile Error: %v", err) |
|
||||||
} |
|
||||||
if !reflect.DeepEqual(config[0], config1) { |
|
||||||
t.Errorf("Got: %v\nExpect: %v\n", config1, config[0]) |
|
||||||
} |
|
||||||
config2, err := ReadProfile(testIniBytes, "testnet") |
|
||||||
if err != nil { |
|
||||||
t.Fatalf("ReadProfile Error: %v", err) |
|
||||||
} |
|
||||||
if !reflect.DeepEqual(config[1], config2) { |
|
||||||
t.Errorf("Got: %v\nExpect: %v\n", config2, config[1]) |
|
||||||
} |
|
||||||
} |
|
@ -1,39 +0,0 @@ |
|||||||
[default] |
|
||||||
bootnode = 127.0.0.1:9000/abcd |
|
||||||
bootnode = 127.0.0.1:9999/daeg |
|
||||||
shards = 4 |
|
||||||
network = mainnet |
|
||||||
|
|
||||||
[default.shard0.rpc] |
|
||||||
rpc = 127.0.0.4:8888 |
|
||||||
rpc = 192.168.0.4:9876 |
|
||||||
|
|
||||||
[default.shard1.rpc] |
|
||||||
rpc = 127.0.0.1:8888 |
|
||||||
rpc = 192.168.0.1:9876 |
|
||||||
|
|
||||||
[default.shard2.rpc] |
|
||||||
rpc = 127.0.0.2:8888 |
|
||||||
rpc = 192.168.0.2:9876 |
|
||||||
|
|
||||||
[default.shard3.rpc] |
|
||||||
rpc = 127.0.0.3:8888 |
|
||||||
rpc = 192.168.0.3:9876 |
|
||||||
|
|
||||||
[testnet] |
|
||||||
bootnode = 192.168.0.1:9990/abcd |
|
||||||
bootnode = 127.0.0.1:8888/daeg |
|
||||||
shards = 3 |
|
||||||
network = testnet |
|
||||||
|
|
||||||
[testnet.shard0.rpc] |
|
||||||
rpc = 192.168.2.3:8888 |
|
||||||
rpc = 192.168.192.3:9877 |
|
||||||
|
|
||||||
[testnet.shard1.rpc] |
|
||||||
rpc = 192.168.2.1:8888 |
|
||||||
rpc = 192.168.192.1:9877 |
|
||||||
|
|
||||||
[testnet.shard2.rpc] |
|
||||||
rpc = 192.168.2.2:8888 |
|
||||||
rpc = 192.168.192.2:9877 |
|
@ -1,3 +1,3 @@ |
|||||||
#!/bin/bash |
#!/bin/bash |
||||||
pkill -9 '^(harmony|txgen|soldier|commander|profiler|beacon|bootnode)$' | sed 's/^/Killed process: /' |
pkill -9 '^(harmony|txgen|soldier|commander|profiler|bootnode)$' | sed 's/^/Killed process: /' |
||||||
rm -rf db-127.0.0.1-* |
rm -rf db-127.0.0.1-* |
||||||
|
Loading…
Reference in new issue