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

heco mainnet

parent e1aadc97
package multisend
import (
"crypto/ecdsa"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)
func buildSendTx(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, chainId *big.Int, privateKey *ecdsa.PrivateKey) (*types.Transaction, error) {
return buildTx(nonce, to, amount, gasLimit, gasPrice, data, chainId, privateKey)
}
func buildOriginalTx(nonce uint64, to common.Address, chainId *big.Int, privateKey *ecdsa.PrivateKey) (*types.Transaction, error) {
return buildTx(nonce, to, big.NewInt(int64(nonce)), 0, big.NewInt(0), nil, chainId, privateKey)
}
func buildTx(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, chainId *big.Int, privateKey *ecdsa.PrivateKey) (*types.Transaction, error) {
tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data)
if privateKey != nil {
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainId), privateKey)
if err != nil {
return nil, err
}
tx = signedTx
}
return tx, nil
}
...@@ -3,48 +3,48 @@ package multisend ...@@ -3,48 +3,48 @@ package multisend
import ( import (
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"math/big" "math/big"
"github.com/go-redis/redis/v8" "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
) )
var privatekey string = "a1994419e9b06a7b27e8d094840ae26a6b7806633bb8be55a1a835f1620d8cec" var sendTxPrivatekey string = "a1994419e9b06a7b27e8d094840ae26a6b7806633bb8be55a1a835f1620d8cec"
var toAddress common.Address = common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d") var toAddress common.Address = common.HexToAddress("0x0071B39fd266F8aeF392fb50F078A233b2218a0b")
var data []byte = make([]byte, 0, md5.Size*(3)) // func RegisterBuildTxParam(name string, factory Param) error {
// if _, exists := buildTxPrama[name]; exists {
// return fmt.Errorf("source param with the specified name already exists: %s", name)
// }
// buildTxPrama[name] = factory
// return nil
// }
func init() { func init() {
privatekey = "a1994419e9b06a7b27e8d094840ae26a6b7806633bb8be55a1a835f1620d8cec" if err := RegisterClientFactory("ethclient", NewEthClientFactory()); err != nil {
for i := 0; i < 3; i++ { panic(err)
hash := md5.Sum([]byte(fmt.Sprintf("%d", i)))
data = append(data, hash[:]...)
} }
} }
type EthClientFactory struct{} type EthClientFactory struct{}
type EthClient struct { type EthClient struct {
NodeRpcURL string PrivateKey *ecdsa.PrivateKey
FromAddr common.Address
NodeUrl string
Nonce uint64
GasPrice *big.Int
ChainId *big.Int
GasLimit uint64
} }
var _ ClientFactory = (*EthClientFactory)(nil) var _ ClientFactory = (*EthClientFactory)(nil)
var _ Client = (*EthClient)(nil) var _ Client = (*EthClient)(nil)
func init() {
if err := RegisterClientFactory("ethclient", NewEthClientFactory()); err != nil {
panic(err)
}
}
func NewEthClientFactory() *EthClientFactory { func NewEthClientFactory() *EthClientFactory {
return &EthClientFactory{} return &EthClientFactory{}
} }
...@@ -54,155 +54,84 @@ func (f *EthClientFactory) ValidateConfig(cfg Config) error { ...@@ -54,155 +54,84 @@ func (f *EthClientFactory) ValidateConfig(cfg Config) error {
} }
func (f *EthClientFactory) NewClient(cfg Config) (Client, error) { 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) sendTxPrivatekeyAsECDSA, err := crypto.HexToECDSA(sendTxPrivatekey)
if err != nil { if err != nil {
return nil, err panic(err)
} }
sendTxPublicKey := sendTxPrivatekeyAsECDSA.Public()
publicKey := privateKeyAsECDSA.Public() sendTxPublicKeyECDSA, ok := sendTxPublicKey.(*ecdsa.PublicKey)
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok { if !ok {
return nil, fmt.Errorf("publicKey.(*ecdsa.PublicKey) not ok") panic("publicKey.(*ecdsa.PublicKey) not ok")
} }
fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA) sendTxFromAddress := crypto.PubkeyToAddress(*sendTxPublicKeyECDSA)
client, err := ethclient.Dial(c.NodeRpcURL)
if err != nil { buildTxParam := EthClient{
return nil, err PrivateKey: sendTxPrivatekeyAsECDSA,
FromAddr: sendTxFromAddress,
//NodeUrl: "http://13.40.31.153:8545",
//https://heco.getblock.io/mainnet/
//NodeUrl: "https://heco.getblock.io/mainnet/",
NodeUrl: "https://http-mainnet-node.huobichain.com",
} }
nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
cli, err := ethclient.Dial(buildTxParam.NodeUrl)
if err != nil { if err != nil {
return nil, err panic(err)
} }
// gasPrice, err := client.SuggestGasPrice(context.Background()) nonce, err := cli.PendingNonceAt(context.Background(), buildTxParam.FromAddr)
// if err != nil {
// return nil, err
// }
// chainID, err := client.NetworkID(context.Background())
// if err != nil {
// return nil, err
// }
txs, md5data, err := getBatchTx(3, c.NodeRpcURL, false)
if err != nil { if err != nil {
return nil, err panic(err)
} }
_ = txs
// gasLimit, err := client.EstimateGas(context.Background(), ethereum.CallMsg{
// To: &toAddress,
// Data: md5data,
// })
//fmt.Printf("gasLimit: %d gasPrice: %d \n", gasLimit, gasPrice) gasPrice, err := cli.SuggestGasPrice(context.Background())
if err != nil {
tx := types.NewTransaction(nonce, toAddress, big.NewInt(10000000000000), 24894, big.NewInt(1000000000), md5data) panic(err)
//tx := types.NewTransaction(nonce, toAddress, big.NewInt(10000000000000), 24894, big.NewInt(1000000000), data) }
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(256)), privateKeyAsECDSA) ChainId, err := cli.NetworkID(context.Background())
if err != nil { if err != nil {
return nil, err panic(err)
} }
return signedTx, nil
}
type Md5tx struct { buildTxParam.Nonce = nonce
MD5 string `json:md5` buildTxParam.GasPrice = gasPrice
Tx *types.Transaction `json:tx` buildTxParam.ChainId = ChainId
return &buildTxParam, nil
} }
var ctx = context.Background() func (c *EthClient) GenerateTx() (*types.Transaction, error) {
var rdb = redis.NewClient(&redis.Options{
Addr: "54.250.115.98:6379",
Password: "redis20220217", // no password set
DB: 0, // use default DB
})
func getBatchTx(txNum int, nodeUrl string, signed bool) ([]Md5tx, []byte, error) {
res := make([]Md5tx, 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++ { select {
tx := types.NewTransaction(0+uint64(i), toAddress, big.NewInt(10000000000000), 4178026, big.NewInt(1000000000), nil) case md5Data := <-originalMd5Queue:
if signed { if c.GasLimit == 0 {
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(256)), privateKeyAsECDSA) cli, err := ethclient.Dial(c.NodeUrl)
if err != nil { if err != nil {
return nil, nil, err panic(err)
} }
tx = signedTx
}
txAsBytes, err := tx.MarshalBinary() gasLimit, err := cli.EstimateGas(context.Background(), ethereum.CallMsg{
if err != nil { To: &toAddress,
return nil, nil, err Data: *md5Data,
} })
if err != nil {
md5Bytes := md5.Sum(txAsBytes) return nil, err
md5Data = append(md5Data, md5Bytes[:]...) }
md5tx := Md5tx{hex.EncodeToString(md5Bytes[:]), tx}
res = append(res, md5tx) c.GasLimit = gasLimit
md5TxAsJson, err := json.Marshal(md5tx) }
tx, err := buildSendTx(c.Nonce, toAddress, big.NewInt(1), c.GasLimit, c.GasPrice, *md5Data, c.ChainId, c.PrivateKey)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
if i == txNum { c.Nonce += 1
err = rdb.LPush(ctx, "list-liwei", md5TxAsJson).Err()
} else {
rdb.LPush(ctx, "list-liwei", md5TxAsJson)
}
if err != nil { return tx, nil
panic(err)
}
} }
return res, md5Data, nil
} }
package multisend
import (
"context"
"crypto/md5"
"encoding/json"
"fmt"
"math/big"
"sync"
"time"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/go-redis/redis/v8"
)
var originalTxParam EthClient
var originTxPrivateKey string = "9e0944f587e1043d6e303644738b0c7c77ed15b176ca574ed0be40c0b9bbdc3a"
var originalMd5Queue chan *[]byte = make(chan *[]byte, 1000)
var originalMd5TxQueue chan *Md5tx = make(chan *Md5tx, 500000)
const batchSize = 8000
func init() {
originTxPrivateKeyAsECDSA, err := crypto.HexToECDSA(originTxPrivateKey)
if err != nil {
panic(err)
}
originalTxParam = EthClient{
PrivateKey: originTxPrivateKeyAsECDSA,
Nonce: 0,
}
}
type Md5tx struct {
MD5 string `json:md5`
Tx *types.Transaction `json:tx`
}
func ProduceOriginalTx() {
for {
//fmt.Printf("len(originalTxQueue): %d len(originalMd5TxQueue): %d \n", len(originalTxQueue), len(originalMd5TxQueue))
if len(originalMd5Queue) < 100 {
var md5Data []byte = make([]byte, 0, md5.Size*(batchSize))
for i := 0; i < batchSize; i++ {
tx, err := buildOriginalTx(originalTxParam.Nonce, toAddress, big.NewInt(256), nil)
if err != nil {
fmt.Println(err.Error())
continue
}
originalTxParam.Nonce += 1
txAsBytes, err := tx.MarshalBinary()
if err != nil {
fmt.Println(err.Error())
continue
}
md5Bytes := md5.Sum(txAsBytes)
md5Data = append(md5Data, md5Bytes[:]...)
}
//startTime := time.Now()
// fp, err := os.Create("bin")
// if err != nil {
// fmt.Println(err)
// return
// }
// defer fp.Close()
// buf := new(bytes.Buffer)
// binary.Write(buf, binary.LittleEndian, md5Data)
// fp.Write(buf.Bytes())
fmt.Printf("len(md5Data): %d \n", len(md5Data))
originalMd5Queue <- &md5Data
//fmt.Printf("time.Since(startTime): %s \n", fmt.Sprintf("%.20f", time.Since(startTime).Seconds()))
//md5tx := Md5tx{hex.EncodeToString(md5Bytes[:]), tx}
//originalMd5TxQueue <- &md5tx
} else {
return
time.Sleep(time.Millisecond * 1)
}
}
}
var ctx = context.Background()
var rdb = redis.NewClient(&redis.Options{
Addr: "54.250.115.98:6379",
Password: "redis20220217", // no password set
DB: 0, // use default DB
})
func SendMd5Tx() {
//超时 超量
// count := 0
// sendTicker := time.NewTicker(time.Duration(5) * time.Second)
for {
// if count > 50 {
// // fmt.Printf("current count: %d \n", count)
// // rdb.Context().Err()
// // sendTicker.Reset(time.Duration(5) * time.Second)
// // count = 0
// }
select {
//case <-sendTicker.C:
// fmt.Printf("5s timeout\n")
// rdb.Context().Err()
// count = 0
case md5Tx := <-originalMd5TxQueue:
md5TxAsJson, err := json.Marshal(md5Tx)
if err != nil {
fmt.Println(err.Error())
continue
}
rdb.LPush(ctx, "list", md5TxAsJson)
}
}
}
func StartProduceTx() {
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
ProduceOriginalTx()
}()
go func() {
defer wg.Done()
SendMd5Tx()
}()
wg.Wait()
}
package multisend
import (
"testing"
)
func TestProduceTx(t *testing.T) {
//StartProduceTx()
ProduceOriginalTx()
}
...@@ -249,7 +249,10 @@ func (t *Transactor) sendTransactions() error { ...@@ -249,7 +249,10 @@ func (t *Transactor) sendTransactions() error {
} }
var sent int var sent int
var sentBytes int64 var sentBytes int64
defer func() { t.trackSentTxs(sent, sentBytes) }() defer func() {
fmt.Printf("sent %d \n", sent)
t.trackSentTxs(sent, sentBytes)
}()
t.logger.Info("Sending batch of transactions", "now", time.Now().Format("15:04:05"), "toSend", toSend) t.logger.Info("Sending batch of transactions", "now", time.Now().Format("15:04:05"), "toSend", toSend)
batchStartTime := time.Now() batchStartTime := time.Now()
for ; sent < toSend; sent++ { for ; sent < toSend; sent++ {
...@@ -280,6 +283,7 @@ func (t *Transactor) sendTransactions() error { ...@@ -280,6 +283,7 @@ func (t *Transactor) sendTransactions() error {
//return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data)) //return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data))
// if we have to make way for the next batch // if we have to make way for the next batch
if time.Since(batchStartTime) >= time.Duration(t.config.SendPeriod)*time.Second { if time.Since(batchStartTime) >= time.Duration(t.config.SendPeriod)*time.Second {
fmt.Printf("time.Since(batchStartTime): %s \n", fmt.Sprintf("%.20f", time.Since(batchStartTime).Seconds()))
break break
} }
} }
......
...@@ -7,16 +7,26 @@ import ( ...@@ -7,16 +7,26 @@ import (
func TestTransactor(t *testing.T) { func TestTransactor(t *testing.T) {
go StartProduceTx()
for {
if len(originalMd5Queue) >= 100 {
break
}
t.Logf("waiting for produce original tx, len(originalMd5Queue):%d \n", len(originalMd5Queue))
time.Sleep(1 * time.Second)
}
cfg := Config{ cfg := Config{
Rate: 2, Rate: 5,
Count: 100, Count: 20,
Connections: 1, Connections: 1,
Time: 100, Time: 100,
SendPeriod: 1, SendPeriod: 3,
ClientFactory: "ethclient", ClientFactory: "ethclient",
} }
//wss://ws-mainnet-node.huobichain.com
transactor, err := NewTransactor("ws://13.40.31.153:8546", &cfg) transactor, err := NewTransactor("wss://ws-mainnet-node.huobichain.com", &cfg)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
...@@ -25,6 +35,6 @@ func TestTransactor(t *testing.T) { ...@@ -25,6 +35,6 @@ func TestTransactor(t *testing.T) {
//transactor.sendLoop() //transactor.sendLoop()
transactor.Start() transactor.Start()
time.Sleep(time.Second * 60) time.Sleep(time.Second * 120)
} }
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