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 package multisend
import ( // import (
"time" // "time"
"code.wuban.net.cn/multisend/internal/logging" // "code.wuban.net.cn/multisend/internal/logging"
) // )
func ExecuteStandalone(cfg Config) error { // func ExecuteStandalone(cfg Config) error {
logger := logging.NewLogrusLogger("loadtest") // logger := logging.NewLogrusLogger("loadtest")
if cfg.ExpectPeers > 0 { // if cfg.ExpectPeers > 0 {
peers, err := waitForEthNetworkPeers( // peers, err := waitForEthNetworkPeers(
cfg.Endpoints, // cfg.Endpoints,
cfg.EndpointSelectMethod, // cfg.EndpointSelectMethod,
cfg.ExpectPeers, // cfg.ExpectPeers,
cfg.MinConnectivity, // cfg.MinConnectivity,
cfg.MaxEndpoints, // cfg.MaxEndpoints,
time.Duration(cfg.PeerConnectTimeout)*time.Second, // time.Duration(cfg.PeerConnectTimeout)*time.Second,
logger, // logger,
) // )
if err != nil { // if err != nil {
logger.Error("Failed while waiting for peers to connect", "err", err) // logger.Error("Failed while waiting for peers to connect", "err", err)
return err // return err
} // }
cfg.Endpoints = peers // cfg.Endpoints = peers
} // }
logger.Info("Connecting to remote endpoints") // logger.Info("Connecting to remote endpoints")
tg := NewTransactorGroup() // tg := NewTransactorGroup()
if err := tg.AddAll(&cfg); err != nil { // if err := tg.AddAll(&cfg); err != nil {
return err // return err
} // }
logger.Info("Initiating load test") // logger.Info("Initiating load test")
tg.Start() // tg.Start()
var cancelTrap chan struct{} // var cancelTrap chan struct{}
if !cfg.NoTrapInterrupts { // if !cfg.NoTrapInterrupts {
// we want to know if the user hits Ctrl+Break // // we want to know if the user hits Ctrl+Break
cancelTrap = trapInterrupts(func() { tg.Cancel() }, logger) // cancelTrap = trapInterrupts(func() { tg.Cancel() }, logger)
defer close(cancelTrap) // defer close(cancelTrap)
} else { // } else {
logger.Debug("Skipping trapping of interrupts (e.g. Ctrl+Break)") // logger.Debug("Skipping trapping of interrupts (e.g. Ctrl+Break)")
} // }
if err := tg.Wait(); err != nil { // if err := tg.Wait(); err != nil {
logger.Error("Failed to execute load test", "err", err) // logger.Error("Failed to execute load test", "err", err)
return err // return err
} // }
logger.Info("Load test complete!") // logger.Info("Load test complete!")
return nil // return nil
} // }
...@@ -13,16 +13,11 @@ import ( ...@@ -13,16 +13,11 @@ import (
"code.wuban.net.cn/multisend/internal/logging" "code.wuban.net.cn/multisend/internal/logging"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
//rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
) )
const ( const (
connSendTimeout = 10 * time.Second connSendTimeout = 10 * time.Second
// see https://github.com/tendermint/tendermint/blob/master/rpc/lib/server/handlers.go connPingPeriod = (30 * 9 / 10) * time.Second
connPingPeriod = (30 * 9 / 10) * time.Second
//jsonRPCID = rpctypes.JSONRPCStringID("tm-load-test")
defaultProgressCallbackInterval = 5 * time.Second defaultProgressCallbackInterval = 5 * time.Second
) )
...@@ -85,12 +80,12 @@ func NewTransactor(remoteAddr string, config *Config) (*Transactor, error) { ...@@ -85,12 +80,12 @@ func NewTransactor(remoteAddr string, config *Config) (*Transactor, error) {
logger := logging.NewLogrusLogger(fmt.Sprintf("transactor[%s]", u.String())) logger := logging.NewLogrusLogger(fmt.Sprintf("transactor[%s]", u.String()))
logger.Info("Connected to remote Tendermint WebSockets RPC") logger.Info("Connected to remote Tendermint WebSockets RPC")
return &Transactor{ return &Transactor{
remoteAddr: u.String(), remoteAddr: u.String(),
config: config, config: config,
client: client, client: client,
logger: logger, logger: logger,
conn: conn, conn: conn,
broadcastTxMethod: "broadcast_tx_" + config.BroadcastTxMethod, //broadcastTxMethod: "broadcast_tx_" + config.BroadcastTxMethod,
progressCallbackInterval: defaultProgressCallbackInterval, progressCallbackInterval: defaultProgressCallbackInterval,
}, nil }, nil
} }
...@@ -178,7 +173,6 @@ func (t *Transactor) sendLoop() { ...@@ -178,7 +173,6 @@ func (t *Transactor) sendLoop() {
} }
return err return err
}) })
pingTicker := time.NewTicker(connPingPeriod) pingTicker := time.NewTicker(connPingPeriod)
timeLimitTicker := time.NewTicker(time.Duration(t.config.Time) * time.Second) timeLimitTicker := time.NewTicker(time.Duration(t.config.Time) * time.Second)
sendTicker := time.NewTicker(time.Duration(t.config.SendPeriod) * time.Second) sendTicker := time.NewTicker(time.Duration(t.config.SendPeriod) * time.Second)
...@@ -223,12 +217,6 @@ func (t *Transactor) sendLoop() { ...@@ -223,12 +217,6 @@ func (t *Transactor) sendLoop() {
} }
func (t *Transactor) writeTx(msg interface{}) error { 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) err := t.conn.WriteJSON(msg)
return err return err
} }
...@@ -248,13 +236,6 @@ func (t *Transactor) setStop(err error) { ...@@ -248,13 +236,6 @@ func (t *Transactor) setStop(err error) {
t.stopMtx.Unlock() 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 { func (t *Transactor) sendTransactions() error {
// send as many transactions as we can, up to the send rate // send as many transactions as we can, up to the send rate
totalSent := t.GetTxCount() totalSent := t.GetTxCount()
...@@ -285,11 +266,10 @@ func (t *Transactor) sendTransactions() error { ...@@ -285,11 +266,10 @@ func (t *Transactor) sendTransactions() error {
args := hexutil.Encode(data) args := hexutil.Encode(data)
method := "eth_sendRawTransaction" method := "eth_sendRawTransaction"
msg, err := t.newMessage(method, args...) msg, err := t.newMessage(method, args)
if err != nil { if err != nil {
return err return err
} }
//op := &requestOp{ids: []json.RawMessage{msg.ID}, resp: make(chan *jsonrpcMessage, 1)} //op := &requestOp{ids: []json.RawMessage{msg.ID}, resp: make(chan *jsonrpcMessage, 1)}
//return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data)) //return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data))
if err := t.writeTx(msg); err != nil { if err := t.writeTx(msg); err != nil {
......
...@@ -2,8 +2,29 @@ package multisend ...@@ -2,8 +2,29 @@ package multisend
import ( import (
"testing" "testing"
"time"
) )
func TestTransactor(t *testing.T) { 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