12 "github.com/pelletier/go-toml"
14 "github.com/spf13/cobra"
16 "github.com/bytom/blockchain/query"
17 "github.com/bytom/util"
21 SendAcct string `toml:"send_acct_id"`
22 Sendasset string `toml:"send_asset_id"`
23 AssetAddr string `toml:"asset_address"`
24 BuildType string `toml:"build_type"`
25 AssetReceiver []string `toml:"asset_receiver"`
26 Password string `toml:"password"`
30 sendTxCmd.PersistentFlags().IntVar(&thdTxNum, "thdtxnum", 10, " The number of transactions per goroutine")
31 sendTxCmd.PersistentFlags().IntVar(&thdNum, "thdnum", 5, "goroutine num")
32 sendTxCmd.PersistentFlags().IntVar(&assetNum, "assetnum", 10, "Number of transactions asset")
33 sendTxCmd.PersistentFlags().StringVar(&configFile, "config", "./config.toml", "config file")
50 var sendTxCmd = &cobra.Command{
52 Short: "send bulk tx",
53 Args: cobra.RangeArgs(0, 4),
54 Run: func(cmd *cobra.Command, args []string) {
55 bs, err := ioutil.ReadFile(configFile)
56 if err = toml.Unmarshal(bs, &cfg); err != nil {
60 sendAcct = cfg.SendAcct
61 sendasset = cfg.Sendasset
62 acctNum = len(cfg.AssetReceiver)
63 controlPrograms := make([]string, acctNum)
64 txidChan := make(chan string)
65 switch cfg.BuildType {
66 case "issue", "spend", "address":
67 for i, value := range cfg.AssetReceiver {
68 controlPrograms[i] = value
71 fmt.Println("Invalid transaction template type")
72 os.Exit(util.ErrLocalExe)
74 txBtm := fmt.Sprintf("%d", assetNum)
75 fmt.Println("*****************send tx start*****************")
76 // send btm to account
77 for i := 0; i < thdNum; i++ {
78 go Sendbulktx(thdTxNum, txBtm, sendAcct, sendasset, controlPrograms, txidChan)
82 go recvTxID(txs, txidChan)
85 blockTxNum := make(map[uint64]uint32)
88 for e := txs.Front(); e != nil; e = n {
89 //fmt.Println(e.Value) //输出list的值,01234
90 value := fmt.Sprintf("%s", e.Value)
91 param := []string{value}
92 if resp, ok := SendReq(GetTransaction, param); ok {
93 var tx query.AnnotatedTx
94 RestoreStruct(resp, &tx)
95 if _, ok := blockTxNum[tx.BlockHeight]; ok {
96 blockTxNum[tx.BlockHeight]++
98 blockTxNum[tx.BlockHeight] = 1
111 if num >= sucess && (sucess+fail) >= thdTxNum*thdNum {
113 fmt.Printf("tx num: %d, use time: %v\n", num, end.Sub(start))
115 for k := range blockTxNum {
116 keys = append(keys, k)
118 for _, key := range keys {
119 fmt.Println("height:", key, ",tx num:", blockTxNum[key])
123 time.Sleep(time.Second * 60)
129 func recvTxID(txs *list.List, txidChan chan string) {
131 file, error := os.OpenFile("./txid.txt", os.O_RDWR|os.O_CREATE, 0766)
138 case txid := <-txidChan:
139 if strings.EqualFold(txid, "") {
146 file.WriteString(txid)
147 file.WriteString("\n")
150 if fail >= (thdTxNum * thdNum) {
153 if (sucess + fail) >= (thdTxNum * thdNum) {
158 time.Sleep(time.Second * 1)
165 if _, err := sendTxCmd.ExecuteC(); err != nil {
166 os.Exit(util.ErrLocalExe)