Commit c66bf6c0 authored by 李伟@五瓣科技's avatar 李伟@五瓣科技

commit tx ok

parent 8b626404
package multisend
import (
"context"
"crypto/ecdsa"
"crypto/md5"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
)
var privatekey string = "a1994419e9b06a7b27e8d094840ae26a6b7806633bb8be55a1a835f1620d8cec"
var toAddress common.Address = common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
// var data []byte = make([]byte, 0, md5.Size*(1000))
// func init() {
// privatekey = "a1994419e9b06a7b27e8d094840ae26a6b7806633bb8be55a1a835f1620d8cec"
// for i := 0; i < 8140; i++ {
// hash := md5.Sum([]byte(fmt.Sprintf("%d", i)))
// data = append(data, hash[:]...)
// }
// }
type EthClientFactory struct{}
type EthClient struct {
NodeRpcURL string
}
var _ ClientFactory = (*EthClientFactory)(nil)
var _ Client = (*EthClient)(nil)
func init() {
if err := RegisterClientFactory("ethclient", NewEthClientFactory()); err != nil {
panic(err)
}
}
func NewEthClientFactory() *EthClientFactory {
return &EthClientFactory{}
}
func (f *EthClientFactory) ValidateConfig(cfg Config) error {
return nil
}
func (f *EthClientFactory) NewClient(cfg Config) (Client, error) {
return &EthClient{
NodeRpcURL: "http://13.40.31.153:8545",
}, nil
}
func (c *EthClient) GenerateTx() (*types.Transaction, error) {
privateKeyAsECDSA, err := crypto.HexToECDSA(privatekey)
if err != nil {
return nil, err
}
publicKey := privateKeyAsECDSA.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
return nil, fmt.Errorf("publicKey.(*ecdsa.PublicKey) not ok")
}
fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
client, err := ethclient.Dial(c.NodeRpcURL)
if err != nil {
return nil, err
}
nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
if err != nil {
return nil, err
}
gasPrice, err := client.SuggestGasPrice(context.Background())
if err != nil {
return nil, err
}
chainID, err := client.NetworkID(context.Background())
if err != nil {
return nil, err
}
txs, md5data, err := getBatchTx(8000, c.NodeRpcURL, false)
if err != nil {
return nil, err
}
_ = txs
gasLimit, err := client.EstimateGas(context.Background(), ethereum.CallMsg{
To: &toAddress,
Data: md5data,
})
tx := types.NewTransaction(nonce, toAddress, big.NewInt(10000000000000), gasLimit, gasPrice, md5data)
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKeyAsECDSA)
if err != nil {
return nil, err
}
return signedTx, nil
}
func getBatchTx(txNum int, nodeUrl string, signed bool) ([]*types.Transaction, []byte, error) {
res := make([]*types.Transaction, 0, txNum)
md5Data := make([]byte, 0, md5.Size*(txNum))
//publicKey := privateKey.Public()
// publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
// if !ok {
// log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
// }
// fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
// cli, err := ethclient.Dial(nodeUrl)
// if err != nil {
// log.Fatal(err)
// }
// nonce, err := cli.PendingNonceAt(context.Background(), fromAddress)
// if err != nil {
// log.Fatal(err)
// }
// gasLimit, err := cli.EstimateGas(context.Background(), ethereum.CallMsg{
// To: &toAddress,
// Data: data,
// })
// gasPrice, err := cli.SuggestGasPrice(context.Background())
// if err != nil {
// log.Fatal(err)
// }
// chainID, _ := cli.NetworkID(context.Background())
// fmt.Printf("gasLimit: %v gasPrice: %v chainID: %v \n", 4178026, 1000000000, 256)
privateKeyAsECDSA, err := crypto.HexToECDSA(privatekey)
if err != nil {
return nil, nil, err
}
for i := 0; i < txNum; i++ {
tx := types.NewTransaction(0+uint64(i), toAddress, big.NewInt(10000000000000), 4178026, big.NewInt(1000000000), nil)
if signed {
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(256)), privateKeyAsECDSA)
//signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), privateKey)
if err != nil {
return nil, nil, err
}
tx = signedTx
}
txAsBytes, err := tx.MarshalBinary()
if err != nil {
return nil, nil, err
}
hash := md5.Sum(txAsBytes)
md5Data = append(md5Data, hash[:]...)
res = append(res, tx)
}
return res, md5Data, nil
}
This diff is collapsed.
This diff is collapsed.
package multisend
import (
"time"
"code.wuban.net.cn/multisend/internal/logging"
)
func ExecuteStandalone(cfg Config) error {
logger := logging.NewLogrusLogger("loadtest")
if cfg.ExpectPeers > 0 {
peers, err := waitForEthNetworkPeers(
cfg.Endpoints,
cfg.EndpointSelectMethod,
cfg.ExpectPeers,
cfg.MinConnectivity,
cfg.MaxEndpoints,
time.Duration(cfg.PeerConnectTimeout)*time.Second,
logger,
)
if err != nil {
logger.Error("Failed while waiting for peers to connect", "err", err)
return err
}
cfg.Endpoints = peers
}
logger.Info("Connecting to remote endpoints")
tg := NewTransactorGroup()
if err := tg.AddAll(&cfg); err != nil {
return err
}
logger.Info("Initiating load test")
tg.Start()
var cancelTrap chan struct{}
if !cfg.NoTrapInterrupts {
// we want to know if the user hits Ctrl+Break
cancelTrap = trapInterrupts(func() { tg.Cancel() }, logger)
defer close(cancelTrap)
} else {
logger.Debug("Skipping trapping of interrupts (e.g. Ctrl+Break)")
}
if err := tg.Wait(); err != nil {
logger.Error("Failed to execute load test", "err", err)
return err
}
logger.Info("Load test complete!")
return nil
}
// import (
// "time"
// "code.wuban.net.cn/multisend/internal/logging"
// )
// func ExecuteStandalone(cfg Config) error {
// logger := logging.NewLogrusLogger("loadtest")
// if cfg.ExpectPeers > 0 {
// peers, err := waitForEthNetworkPeers(
// cfg.Endpoints,
// cfg.EndpointSelectMethod,
// cfg.ExpectPeers,
// cfg.MinConnectivity,
// cfg.MaxEndpoints,
// time.Duration(cfg.PeerConnectTimeout)*time.Second,
// logger,
// )
// if err != nil {
// logger.Error("Failed while waiting for peers to connect", "err", err)
// return err
// }
// cfg.Endpoints = peers
// }
// logger.Info("Connecting to remote endpoints")
// tg := NewTransactorGroup()
// if err := tg.AddAll(&cfg); err != nil {
// return err
// }
// logger.Info("Initiating load test")
// tg.Start()
// var cancelTrap chan struct{}
// if !cfg.NoTrapInterrupts {
// // we want to know if the user hits Ctrl+Break
// cancelTrap = trapInterrupts(func() { tg.Cancel() }, logger)
// defer close(cancelTrap)
// } else {
// logger.Debug("Skipping trapping of interrupts (e.g. Ctrl+Break)")
// }
// if err := tg.Wait(); err != nil {
// logger.Error("Failed to execute load test", "err", err)
// return err
// }
// logger.Info("Load test complete!")
// return nil
// }
......@@ -13,16 +13,11 @@ import (
"code.wuban.net.cn/multisend/internal/logging"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/gorilla/websocket"
//rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
)
const (
connSendTimeout = 10 * time.Second
// see https://github.com/tendermint/tendermint/blob/master/rpc/lib/server/handlers.go
connPingPeriod = (30 * 9 / 10) * time.Second
//jsonRPCID = rpctypes.JSONRPCStringID("tm-load-test")
defaultProgressCallbackInterval = 5 * time.Second
)
......@@ -90,7 +85,7 @@ func NewTransactor(remoteAddr string, config *Config) (*Transactor, error) {
client: client,
logger: logger,
conn: conn,
broadcastTxMethod: "broadcast_tx_" + config.BroadcastTxMethod,
//broadcastTxMethod: "broadcast_tx_" + config.BroadcastTxMethod,
progressCallbackInterval: defaultProgressCallbackInterval,
}, nil
}
......@@ -178,7 +173,6 @@ func (t *Transactor) sendLoop() {
}
return err
})
pingTicker := time.NewTicker(connPingPeriod)
timeLimitTicker := time.NewTicker(time.Duration(t.config.Time) * time.Second)
sendTicker := time.NewTicker(time.Duration(t.config.SendPeriod) * time.Second)
......@@ -223,12 +217,6 @@ func (t *Transactor) sendLoop() {
}
func (t *Transactor) writeTx(msg interface{}) error {
// txBase64 := base64.StdEncoding.EncodeToString(tx)
// paramsJSON, err := json.Marshal(map[string]interface{}{"tx": txBase64})
// if err != nil {
// return err
// }
// _ = t.conn.SetWriteDeadline(time.Now().Add(connSendTimeout))
err := t.conn.WriteJSON(msg)
return err
}
......@@ -248,13 +236,6 @@ func (t *Transactor) setStop(err error) {
t.stopMtx.Unlock()
}
// type requestOp struct {
// ids []json.RawMessage
// err error
// resp chan *jsonrpcMessage // receives up to len(ids) responses
// sub *ClientSubscription // only set for EthSubscribe requests
// }
func (t *Transactor) sendTransactions() error {
// send as many transactions as we can, up to the send rate
totalSent := t.GetTxCount()
......@@ -285,11 +266,10 @@ func (t *Transactor) sendTransactions() error {
args := hexutil.Encode(data)
method := "eth_sendRawTransaction"
msg, err := t.newMessage(method, args...)
msg, err := t.newMessage(method, args)
if err != nil {
return err
}
//op := &requestOp{ids: []json.RawMessage{msg.ID}, resp: make(chan *jsonrpcMessage, 1)}
//return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data))
if err := t.writeTx(msg); err != nil {
......
......@@ -2,8 +2,29 @@ package multisend
import (
"testing"
"time"
)
func TestTransactor(t *testing.T) {
cfg := Config{
Rate: 10,
Count: 10,
Connections: 1,
Time: 60,
SendPeriod: 10,
ClientFactory: "ethclient",
}
transactor, err := NewTransactor("ws://13.40.31.153:8546", &cfg)
if err != nil {
t.Error(err)
}
//transactor.sendTransactions()
//transactor.sendLoop()
transactor.Start()
time.Sleep(time.Second * 60)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment