github.com/DxChainNetwork/dxc@v0.8.1-0.20220824085222-1162e304b6e7/cmd/stress-test/exec.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"math/big"
     8  	"time"
     9  
    10  	"github.com/DxChainNetwork/dxc/accounts/abi/bind"
    11  	"github.com/DxChainNetwork/dxc/cmd/utils"
    12  	"github.com/DxChainNetwork/dxc/common"
    13  	"github.com/DxChainNetwork/dxc/log"
    14  	"github.com/DxChainNetwork/dxc/params"
    15  	"gopkg.in/urfave/cli.v1"
    16  )
    17  
    18  var commandStressTestNormal = cli.Command{
    19  	Name:  "testNormal",
    20  	Usage: "Send normal transfer transactions for stress test",
    21  	Flags: []cli.Flag{
    22  		nodeURLFlag,
    23  		privKeyFlag,
    24  		accountNumberFlag,
    25  		totalTxsFlag,
    26  		threadsFlag,
    27  	},
    28  	Action: utils.MigrateFlags(stressTestNormal),
    29  }
    30  
    31  var commandStressTestToken = cli.Command{
    32  	Name:  "testToken",
    33  	Usage: "Send token transfer transactions for stress test",
    34  	Flags: []cli.Flag{
    35  		nodeURLFlag,
    36  		privKeyFlag,
    37  		accountNumberFlag,
    38  		totalTxsFlag,
    39  		threadsFlag,
    40  		tokenFlag,
    41  		decimalFlag,
    42  	},
    43  	Action: utils.MigrateFlags(stressTestToken),
    44  }
    45  
    46  func stressTestNormal(ctx *cli.Context) error {
    47  	return stressTest(ctx, common.Address{}, 0)
    48  }
    49  
    50  func stressTestToken(ctx *cli.Context) error {
    51  	token := common.HexToAddress(ctx.String(tokenFlag.Name))
    52  	decimal := ctx.Int(decimalFlag.Name)
    53  	if decimal > 18 || decimal <= 0 {
    54  		return fmt.Errorf("Unsupported decimal %d", decimal)
    55  	}
    56  
    57  	return stressTest(ctx, token, decimal)
    58  }
    59  
    60  func stressTest(ctx *cli.Context, token common.Address, decimal int) error {
    61  
    62  	clients := newClients(getRPCList(ctx))
    63  	if len(clients) == 0 {
    64  		return errors.New("no rpc url set")
    65  	}
    66  
    67  	var (
    68  		client        = clients[0]
    69  		mainAccount   = newAccount(ctx.GlobalString(privKeyFlag.Name))
    70  		accountAmount = ctx.Int(accountNumberFlag.Name)
    71  		total         = ctx.Int(totalTxsFlag.Name)
    72  		threads       = ctx.Int(threadsFlag.Name)
    73  	)
    74  
    75  	if total < accountAmount {
    76  		return errors.New("total tx amount should bigger than account amount")
    77  	}
    78  
    79  	first := false
    80  	var accounts []*bind.TransactOpts
    81  	var toGen int
    82  	keys, err := loadAccounts(getStorePath())
    83  	if err != nil {
    84  		log.Warn("load accounts failed", "err", err)
    85  		first = true
    86  		toGen = accountAmount
    87  	}
    88  	log.Info("load original accounts", "amount", len(keys))
    89  
    90  	if !first && accountAmount > len(keys) {
    91  		toGen = accountAmount - len(keys)
    92  	}
    93  
    94  	if len(keys) > 0 {
    95  		accounts = append(accounts, newAccounts(keys)...)
    96  	}
    97  
    98  	if toGen > 0 {
    99  		genKeys, genAccounts := generateRandomAccounts(toGen)
   100  		log.Info("generate accounts over", "generated", len(genAccounts))
   101  
   102  		accounts = append(accounts, genAccounts...)
   103  		if first {
   104  			if err := writeAccounts(getStorePath(), genKeys); err != nil {
   105  				return err
   106  			}
   107  		} else {
   108  			if err := appendAccounts(getStorePath(), genKeys); err != nil {
   109  				return err
   110  			}
   111  		}
   112  
   113  		// send this accounts hb and hsct.
   114  		// send ether from main account to random account
   115  		log.Info("send hb and token to test account")
   116  		amount := big.NewInt(params.Ether)
   117  		amount.Mul(amount, big.NewInt(100))
   118  
   119  		// send hb for normal hb transfer test or pay gas fees
   120  		sendEtherToRandomAccount(mainAccount, accounts, amount, common.Address{}, client)
   121  
   122  		// send token to accounts.
   123  		amount.Div(amount, divisor(defaultDecimal-decimal))
   124  		sendEtherToRandomAccount(mainAccount, accounts, amount, token, client)
   125  	}
   126  
   127  	accounts = accounts[:accountAmount]
   128  
   129  	// generate signed transactions
   130  	amount := big.NewInt(params.Ether)
   131  	amount.Div(amount, big.NewInt(1e+3))
   132  	if (token != common.Address{}) {
   133  		amount.Div(amount, divisor(defaultDecimal-decimal))
   134  	}
   135  	txs := generateSignedTransactions(total, accounts, amount, token, client)
   136  	log.Info("generate txs over", "total", len(txs))
   137  
   138  	currentBlock, _ := client.BlockByNumber(context.Background(), nil)
   139  	log.Info("current block", "number", currentBlock.Number())
   140  
   141  	// send txs
   142  	start := time.Now()
   143  	stressSendTransactions(txs, threads, clients, client)
   144  	log.Info("send transaction over", "cost(milliseconds)", time.Now().Sub(start).Milliseconds())
   145  
   146  	return nil
   147  }