Merge pull request #88 from getamis/feature/generate-account-for-load-testing
container, k8s, tests: generate more accounts for load testing
This commit is contained in:
commit
9cd60a5e53
|
@ -504,8 +504,13 @@ func (bc *blockchain) setupValidators(ips []net.IP, keys []*ecdsa.PrivateKey, of
|
||||||
opts = append(opts, HostWebSocketPort(freeport.GetPort()))
|
opts = append(opts, HostWebSocketPort(freeport.GetPort()))
|
||||||
opts = append(opts, Key(keys[i]))
|
opts = append(opts, Key(keys[i]))
|
||||||
opts = append(opts, HostIP(ips[i]))
|
opts = append(opts, HostIP(ips[i]))
|
||||||
|
|
||||||
accounts := bc.accounts[i+offset : i+offset+1]
|
accounts := bc.accounts[i+offset : i+offset+1]
|
||||||
opts = append(opts, Accounts(accounts))
|
var addrs []common.Address
|
||||||
|
for _, acc := range accounts {
|
||||||
|
addrs = append(addrs, acc.Address)
|
||||||
|
}
|
||||||
|
opts = append(opts, Accounts(addrs))
|
||||||
|
|
||||||
// Add PRIVATE_CONFIG for quorum
|
// Add PRIVATE_CONFIG for quorum
|
||||||
if bc.isQuorum {
|
if bc.isQuorum {
|
||||||
|
|
|
@ -36,7 +36,6 @@ import (
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
docker "github.com/docker/docker/client"
|
docker "github.com/docker/docker/client"
|
||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
|
@ -86,7 +85,7 @@ type Ethereum interface {
|
||||||
StartMining() error
|
StartMining() error
|
||||||
StopMining() error
|
StopMining() error
|
||||||
|
|
||||||
Accounts() []accounts.Account
|
Accounts() []common.Address
|
||||||
|
|
||||||
DockerEnv() []string
|
DockerEnv() []string
|
||||||
DockerBinds() []string
|
DockerBinds() []string
|
||||||
|
@ -135,7 +134,7 @@ type ethereum struct {
|
||||||
hostName string
|
hostName string
|
||||||
containerID string
|
containerID string
|
||||||
node *discover.Node
|
node *discover.Node
|
||||||
accounts []accounts.Account
|
accounts []common.Address
|
||||||
password string
|
password string
|
||||||
|
|
||||||
//Quorum only
|
//Quorum only
|
||||||
|
@ -672,7 +671,7 @@ func (eth *ethereum) StopMining() error {
|
||||||
return client.StopMining(context.Background())
|
return client.StopMining(context.Background())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (eth *ethereum) Accounts() []accounts.Account {
|
func (eth *ethereum) Accounts() []common.Address {
|
||||||
return eth.accounts
|
return eth.accounts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Option func(*ethereum)
|
type Option func(*ethereum)
|
||||||
|
@ -293,7 +293,7 @@ func NoUSB() Option {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Accounts(accounts []accounts.Account) Option {
|
func Accounts(accounts []common.Address) Option {
|
||||||
return func(eth *ethereum) {
|
return func(eth *ethereum) {
|
||||||
eth.accounts = accounts
|
eth.accounts = accounts
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,21 +17,36 @@
|
||||||
package k8s
|
package k8s
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
||||||
"github.com/getamis/istanbul-tools/charts"
|
"github.com/getamis/istanbul-tools/charts"
|
||||||
istcommon "github.com/getamis/istanbul-tools/common"
|
istcommon "github.com/getamis/istanbul-tools/common"
|
||||||
"github.com/getamis/istanbul-tools/container"
|
"github.com/getamis/istanbul-tools/container"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewBlockchain(numOfValidators int, gaslimit uint64, options ...Option) (bc *blockchain) {
|
func NewBlockchain(numOfValidators int, numOfExtraAccounts int, gaslimit uint64, options ...Option) (bc *blockchain) {
|
||||||
_, nodekeys, addrs := istcommon.GenerateKeys(numOfValidators)
|
_, nodekeys, addrs := istcommon.GenerateKeys(numOfValidators)
|
||||||
ips := istcommon.GenerateIPs(len(nodekeys))
|
ips := istcommon.GenerateIPs(len(nodekeys))
|
||||||
|
|
||||||
|
extraKeys := make([][]*ecdsa.PrivateKey, numOfValidators)
|
||||||
|
extraAddrs := make([][]common.Address, numOfValidators)
|
||||||
|
|
||||||
|
allAddrs := addrs
|
||||||
|
|
||||||
|
if numOfExtraAccounts > 0 {
|
||||||
|
for i := 0; i < numOfValidators; i++ {
|
||||||
|
extraKeys[i], _, extraAddrs[i] = istcommon.GenerateKeys(numOfExtraAccounts)
|
||||||
|
allAddrs = append(allAddrs, extraAddrs[i]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bc = &blockchain{
|
bc = &blockchain{
|
||||||
genesis: charts.NewGenesisChart(addrs, uint64(gaslimit)),
|
genesis: charts.NewGenesisChart(allAddrs, uint64(gaslimit)),
|
||||||
staticNodes: charts.NewStaticNodesChart(nodekeys, ips),
|
staticNodes: charts.NewStaticNodesChart(nodekeys, ips),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +59,7 @@ func NewBlockchain(numOfValidators int, gaslimit uint64, options ...Option) (bc
|
||||||
bc.genesis.Uninstall()
|
bc.genesis.Uninstall()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
bc.setupValidators(numOfValidators, nodekeys, ips, options...)
|
bc.setupValidators(numOfValidators, extraKeys, nodekeys, ips, options...)
|
||||||
return bc
|
return bc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +119,7 @@ func (bc *blockchain) Validators() []container.Ethereum {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
func (bc *blockchain) setupValidators(num int, nodekeys []string, ips []string, options ...Option) {
|
func (bc *blockchain) setupValidators(num int, extraKeys [][]*ecdsa.PrivateKey, nodekeys []string, ips []string, options ...Option) {
|
||||||
for i := 0; i < num; i++ {
|
for i := 0; i < num; i++ {
|
||||||
var opts []Option
|
var opts []Option
|
||||||
opts = append(opts, options...)
|
opts = append(opts, options...)
|
||||||
|
@ -112,6 +127,7 @@ func (bc *blockchain) setupValidators(num int, nodekeys []string, ips []string,
|
||||||
opts = append(opts, Name(fmt.Sprintf("%d", i)))
|
opts = append(opts, Name(fmt.Sprintf("%d", i)))
|
||||||
opts = append(opts, NodeKeyHex(nodekeys[i]))
|
opts = append(opts, NodeKeyHex(nodekeys[i]))
|
||||||
opts = append(opts, IPAddress(ips[i]))
|
opts = append(opts, IPAddress(ips[i]))
|
||||||
|
opts = append(opts, ExtraAccounts(extraKeys[i]))
|
||||||
|
|
||||||
geth := NewEthereum(
|
geth := NewEthereum(
|
||||||
opts...,
|
opts...,
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
func ExampleK8SBlockchain() {
|
func ExampleK8SBlockchain() {
|
||||||
chain := NewBlockchain(
|
chain := NewBlockchain(
|
||||||
4,
|
4,
|
||||||
|
0,
|
||||||
21000*1000,
|
21000*1000,
|
||||||
ImageRepository("quay.io/amis/geth"),
|
ImageRepository("quay.io/amis/geth"),
|
||||||
ImageTag("istanbul_develop"),
|
ImageTag("istanbul_develop"),
|
||||||
|
|
|
@ -28,7 +28,6 @@ import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
||||||
|
@ -66,6 +65,7 @@ type ethereum struct {
|
||||||
|
|
||||||
nodekey string
|
nodekey string
|
||||||
key *ecdsa.PrivateKey
|
key *ecdsa.PrivateKey
|
||||||
|
accounts []*ecdsa.PrivateKey
|
||||||
k8sClient *kubernetes.Clientset
|
k8sClient *kubernetes.Clientset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,8 +351,11 @@ func (eth *ethereum) StopMining() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (eth *ethereum) Accounts() []accounts.Account {
|
func (eth *ethereum) Accounts() (addrs []common.Address) {
|
||||||
return nil
|
for _, acc := range eth.accounts {
|
||||||
|
addrs = append(addrs, crypto.PubkeyToAddress(acc.PublicKey))
|
||||||
|
}
|
||||||
|
return addrs
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -16,7 +16,10 @@
|
||||||
|
|
||||||
package k8s
|
package k8s
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
type Option func(*ethereum)
|
type Option func(*ethereum)
|
||||||
|
|
||||||
|
@ -86,3 +89,9 @@ func Verbosity(verbosity int) Option {
|
||||||
eth.args = append(eth.args, fmt.Sprintf("ethereum.verbosity=%d", verbosity))
|
eth.args = append(eth.args, fmt.Sprintf("ethereum.verbosity=%d", verbosity))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExtraAccounts(keys []*ecdsa.PrivateKey) Option {
|
||||||
|
return func(eth *ethereum) {
|
||||||
|
eth.accounts = keys
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,39 +18,51 @@ package k8s
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
|
||||||
|
"github.com/getamis/istanbul-tools/client"
|
||||||
istcommon "github.com/getamis/istanbul-tools/common"
|
istcommon "github.com/getamis/istanbul-tools/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Transactor interface {
|
type Transactor interface {
|
||||||
SendTransactions(context.Context, common.Address, *big.Int, time.Duration) error
|
SendTransactions(*client.Client, *big.Int, time.Duration) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (eth *ethereum) SendTransactions(ctx context.Context, to common.Address, amount *big.Int, duration time.Duration) error {
|
func (eth *ethereum) SendTransactions(client *client.Client, amount *big.Int, duration time.Duration) error {
|
||||||
client := eth.NewClient()
|
var fns []func() error
|
||||||
if client == nil {
|
for i, key := range eth.accounts {
|
||||||
return errors.New("failed to retrieve client")
|
i := i
|
||||||
}
|
key := key
|
||||||
|
|
||||||
nonce, err := client.NonceAt(context.Background(), eth.Address(), nil)
|
fn := func() error {
|
||||||
if err != nil {
|
fromAddr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
log.Error("Failed to get nonce", "addr", eth.Address(), "err", err)
|
toAddr := crypto.PubkeyToAddress(eth.accounts[(i+1)%len(eth.accounts)].PublicKey)
|
||||||
return err
|
timeout := time.After(duration)
|
||||||
}
|
|
||||||
|
|
||||||
timeout := time.After(duration)
|
nonce, err := client.NonceAt(context.Background(), fromAddr, nil)
|
||||||
for {
|
if err != nil {
|
||||||
select {
|
log.Error("Failed to get nonce", "addr", fromAddr, "err", err)
|
||||||
case <-timeout:
|
return err
|
||||||
return nil
|
}
|
||||||
default:
|
|
||||||
_ = istcommon.SendEther(client, eth.key, to, amount, nonce)
|
for {
|
||||||
nonce++
|
select {
|
||||||
|
case <-timeout:
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
if err := istcommon.SendEther(client, key, toAddr, amount, nonce); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
nonce++
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fns = append(fns, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return executeInParallel(fns...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
package load
|
package load
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -42,12 +41,10 @@ var _ = Describe("TPS-01: Large amount of transactions", func() {
|
||||||
runTests(numberOfValidators, gaslimit, txpoolSize)
|
runTests(numberOfValidators, gaslimit, txpoolSize)
|
||||||
},
|
},
|
||||||
|
|
||||||
tests.Case("2048", 2048),
|
|
||||||
tests.Case("10240", 10240),
|
tests.Case("10240", 10240),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
tests.Case("21000*1000", 21000*1000),
|
|
||||||
tests.Case("21000*3000", 21000*3000),
|
tests.Case("21000*3000", 21000*3000),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -63,12 +60,14 @@ func runTests(numberOfValidators int, gaslimit int, txpoolSize int) {
|
||||||
blockchain container.Blockchain
|
blockchain container.Blockchain
|
||||||
sendEtherAddrs map[common.Address]common.Address
|
sendEtherAddrs map[common.Address]common.Address
|
||||||
|
|
||||||
duration = 10 * time.Minute
|
duration = 10 * time.Minute
|
||||||
|
accountsPerGeth = 30
|
||||||
)
|
)
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
blockchain = k8s.NewBlockchain(
|
blockchain = k8s.NewBlockchain(
|
||||||
numberOfValidators,
|
numberOfValidators,
|
||||||
|
accountsPerGeth,
|
||||||
uint64(gaslimit),
|
uint64(gaslimit),
|
||||||
k8s.ImageRepository("quay.io/amis/geth"),
|
k8s.ImageRepository("quay.io/amis/geth"),
|
||||||
k8s.ImageTag("istanbul_develop"),
|
k8s.ImageTag("istanbul_develop"),
|
||||||
|
@ -104,13 +103,13 @@ func runTests(numberOfValidators int, gaslimit int, txpoolSize int) {
|
||||||
transactor, ok := geth.(k8s.Transactor)
|
transactor, ok := geth.(k8s.Transactor)
|
||||||
Expect(ok).To(BeTrue())
|
Expect(ok).To(BeTrue())
|
||||||
|
|
||||||
Expect(
|
client := geth.NewClient()
|
||||||
transactor.SendTransactions(
|
Expect(client).NotTo(BeNil())
|
||||||
context.Background(),
|
|
||||||
sendEtherAddrs[geth.Address()],
|
Expect(transactor.SendTransactions(
|
||||||
new(big.Int).Exp(big.NewInt(10), big.NewInt(3), nil),
|
client,
|
||||||
duration),
|
new(big.Int).Exp(big.NewInt(10), big.NewInt(3), nil),
|
||||||
).To(BeNil())
|
duration)).To(BeNil())
|
||||||
|
|
||||||
wg.Done()
|
wg.Done()
|
||||||
})
|
})
|
||||||
|
|
|
@ -72,7 +72,7 @@ var _ = Describe("QFS-08: Private transaction", func() {
|
||||||
acc := geth0.Accounts()[0]
|
acc := geth0.Accounts()[0]
|
||||||
client0 := geth0.NewClient()
|
client0 := geth0.NewClient()
|
||||||
byteCode := genByteCodeWithValue(storedValue)
|
byteCode := genByteCodeWithValue(storedValue)
|
||||||
hash, err := client0.CreateContract(context.Background(), acc.Address, byteCode, big.NewInt(300000))
|
hash, err := client0.CreateContract(context.Background(), acc, byteCode, big.NewInt(300000))
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
txHash = common.HexToHash(hash)
|
txHash = common.HexToHash(hash)
|
||||||
})
|
})
|
||||||
|
@ -105,7 +105,7 @@ var _ = Describe("QFS-08: Private transaction", func() {
|
||||||
ct1 := constellationNetwork.GetConstellation(1)
|
ct1 := constellationNetwork.GetConstellation(1)
|
||||||
pubKey1 := ct1.PublicKeys()
|
pubKey1 := ct1.PublicKeys()
|
||||||
byteCode := genByteCodeWithValue(storedValue)
|
byteCode := genByteCodeWithValue(storedValue)
|
||||||
hash, err := client0.CreatePrivateContract(context.Background(), acc.Address, byteCode, big.NewInt(300000), pubKey1)
|
hash, err := client0.CreatePrivateContract(context.Background(), acc, byteCode, big.NewInt(300000), pubKey1)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
txHash = common.HexToHash(hash)
|
txHash = common.HexToHash(hash)
|
||||||
})
|
})
|
||||||
|
@ -136,7 +136,7 @@ var _ = Describe("QFS-08: Private transaction", func() {
|
||||||
ct3 := constellationNetwork.GetConstellation(3)
|
ct3 := constellationNetwork.GetConstellation(3)
|
||||||
pubKey3 := ct3.PublicKeys()
|
pubKey3 := ct3.PublicKeys()
|
||||||
byteCode := genByteCodeWithValue(storedValue)
|
byteCode := genByteCodeWithValue(storedValue)
|
||||||
hash, err := client2.CreatePrivateContract(context.Background(), acc.Address, byteCode, big.NewInt(300000), pubKey3)
|
hash, err := client2.CreatePrivateContract(context.Background(), acc, byteCode, big.NewInt(300000), pubKey3)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
txHash = common.HexToHash(hash)
|
txHash = common.HexToHash(hash)
|
||||||
})
|
})
|
||||||
|
@ -165,7 +165,7 @@ var _ = Describe("QFS-08: Private transaction", func() {
|
||||||
acc := geth0.Accounts()[0]
|
acc := geth0.Accounts()[0]
|
||||||
client0 := geth0.NewClient()
|
client0 := geth0.NewClient()
|
||||||
byteCode := genByteCodeWithValue(storedValue)
|
byteCode := genByteCodeWithValue(storedValue)
|
||||||
hash, err := client0.CreateContract(context.Background(), acc.Address, byteCode, big.NewInt(300000))
|
hash, err := client0.CreateContract(context.Background(), acc, byteCode, big.NewInt(300000))
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
txHash = common.HexToHash(hash)
|
txHash = common.HexToHash(hash)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue