OSDN Git Service

9a41260a1ee2cf39ad0b951bf7629e8980fd5c85
[bytom/bytom.git] / tools / sendbulktx / core / tool.go
1 package core
2
3 import (
4         "container/list"
5         "fmt"
6         "io/ioutil"
7         "os"
8         "strings"
9         "sync"
10         "time"
11
12         "github.com/pelletier/go-toml"
13
14         "github.com/spf13/cobra"
15
16         "github.com/bytom/blockchain/query"
17         "github.com/bytom/util"
18 )
19
20 type config struct {
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"`
27 }
28
29 func init() {
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")
34 }
35
36 var (
37         acctNum    int
38         thdTxNum   int
39         thdNum     int
40         assetNum   int
41         sendAcct   string
42         sendasset  string
43         configFile string
44         cfg        config
45         m          sync.Mutex
46         sucess     = 0
47         fail       = 0
48 )
49
50 var sendTxCmd = &cobra.Command{
51         Use:   "sendbulktx",
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 {
57                         fmt.Println(err)
58                         return
59                 }
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
69                         }
70                 default:
71                         fmt.Println("Invalid transaction template type")
72                         os.Exit(util.ErrLocalExe)
73                 }
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)
79                 }
80
81                 txs := list.New()
82                 go recvTxID(txs, txidChan)
83                 num := 0
84                 start := time.Now()
85                 blockTxNum := make(map[uint64]uint32)
86                 for {
87                         var n *list.Element
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]++
97                                         } else {
98                                                 blockTxNum[tx.BlockHeight] = 1
99                                         }
100                                         n = e.Next()
101                                         m.Lock()
102                                         txs.Remove(e)
103                                         m.Unlock()
104                                         num++
105                                         continue
106                                 } else {
107                                         n = e.Next()
108                                 }
109
110                         }
111                         if num >= sucess && (sucess+fail) >= thdTxNum*thdNum {
112                                 end := time.Now()
113                                 fmt.Printf("tx num: %d, use time: %v\n", num, end.Sub(start))
114                                 var keys []uint64
115                                 for k := range blockTxNum {
116                                         keys = append(keys, k)
117                                 }
118                                 for _, key := range keys {
119                                         fmt.Println("height:", key, ",tx num:", blockTxNum[key])
120                                 }
121                                 os.Exit(0)
122                         }
123                         time.Sleep(time.Second * 60)
124                 }
125
126         },
127 }
128
129 func recvTxID(txs *list.List, txidChan chan string) {
130
131         file, error := os.OpenFile("./txid.txt", os.O_RDWR|os.O_CREATE, 0766)
132         if error != nil {
133                 fmt.Println(error)
134         }
135
136         for {
137                 select {
138                 case txid := <-txidChan:
139                         if strings.EqualFold(txid, "") {
140                                 fail++
141                         } else {
142                                 sucess++
143                                 m.Lock()
144                                 txs.PushBack(txid)
145                                 m.Unlock()
146                                 file.WriteString(txid)
147                                 file.WriteString("\n")
148                         }
149                 default:
150                         if fail >= (thdTxNum * thdNum) {
151                                 os.Exit(1)
152                         }
153                         if (sucess + fail) >= (thdTxNum * thdNum) {
154                                 file.Close()
155                                 return
156                         }
157
158                         time.Sleep(time.Second * 1)
159                 }
160         }
161 }
162
163 // Execute send tx
164 func Execute() {
165         if _, err := sendTxCmd.ExecuteC(); err != nil {
166                 os.Exit(util.ErrLocalExe)
167         }
168 }