Documentation ¶
Index ¶
Constants ¶
const ( None int = iota TransferTx ContractTransferTx GasTx RAMTx AccountTx ExchangeTransferTx )
The type of transaction.
Variables ¶
var AccountCaseAction = func(c *cli.Context) error { anum := c.GlobalInt("anum") output := c.GlobalString("account") keysfile := c.GlobalString("keys") configfile := c.GlobalString("config") it, err := itest.Load(keysfile, configfile) if err != nil { return err } accounts, err := it.CreateAccountN(anum, false, true) if err != nil { return err } if err := itest.DumpAccounts(accounts, output); err != nil { return err } return nil }
AccountCaseAction is the action of account test case
var AccountCaseCommand = cli.Command{ Name: "account_case", ShortName: "a_case", Usage: "run account test case", Action: AccountCaseAction, }
AccountCaseCommand is the command of account test case
var AccountRoundAction = func(c *cli.Context) error { itest.Interval = 2 * time.Millisecond itest.InitAmount = "1000" itest.InitPledge = "1000" itest.InitRAM = "3000" logger := ilog.New() fileWriter := ilog.NewFileWriter(c.GlobalString("log")) fileWriter.SetLevel(ilog.LevelInfo) logger.AddWriter(fileWriter) ilog.InitLogger(logger) keysfile := c.GlobalString("keys") configfile := c.GlobalString("config") it, err := itest.Load(keysfile, configfile) if err != nil { return err } start := c.Int("start") round := c.Int("round") for i := start; i < start+round; i++ { accounts, err := it.CreateAccountRoundN(10000, false, true, i) if err != nil { return err } outputFile := "output_acc" + strconv.FormatInt(int64(i), 10) + ".json" ilog.Infof("before dump account %v\n", outputFile) if err := itest.DumpAccounts(accounts, outputFile); err != nil { return err } } return nil }
AccountRoundAction is the action of account test round
var AccountRoundCommand = cli.Command{ Name: "account_round", ShortName: "a_round", Usage: "run account test round", Flags: AccountRoundFlags, Action: AccountRoundAction, }
AccountRoundCommand is the command of account test round
var AccountRoundFlags = []cli.Flag{ cli.IntFlag{ Name: "start", Value: 1, Usage: "start round", }, cli.IntFlag{ Name: "round", Value: 100, Usage: "round number", }, }
AccountRoundFlags is the list of flags for account round.
var BenchmarkAccountAction = func(c *cli.Context) error { rand.Seed(time.Now().UTC().UnixNano()) itest.Interval = 1000 * time.Millisecond itest.InitAmount = "1000" itest.InitPledge = "1000" itest.InitRAM = "3000" it, err := itest.Load(c.GlobalString("keys"), c.GlobalString("config")) if err != nil { return err } accountFile := c.GlobalString("account") accounts, err := itest.LoadAccounts(accountFile) if err != nil { ilog.Warnf("load accounts from %v failed, creating...%v", accountFile, err) if err := AccountCaseAction(c); err != nil { return err } if accounts, err = itest.LoadAccounts(accountFile); err != nil { return err } } ilog.Infof("accounts num %v", len(accounts)) tps := c.Int("tps") ilog.Infof("target tps %v", tps) sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) startTime := time.Now() ticker := time.NewTicker(time.Second) counter := 0 total := 0 slotTotal := 0 slotStartTime := startTime checkReceiptConcurrent := 64 hashCh := make(chan *hashItem, 4*tps*int(itest.Timeout.Seconds())) for c := 0; c < checkReceiptConcurrent; c++ { go func(hashCh chan *hashItem) { counter := 0 failedCounter := 0 for item := range hashCh { client := it.GetClients()[rand.Intn(len(it.GetClients()))] _, err := client.CheckTransactionWithTimeout(item.hash, item.expire) counter++ if err != nil { ilog.Errorf("check transaction failed, %v", err) failedCounter++ } if counter%1000 == 0 { ilog.Warnf("check %v transaction, %v successful, %v failed.", counter, counter-failedCounter, failedCounter) } if len(hashCh) > 3*tps*int(itest.Timeout.Seconds()) { ilog.Infof("hash ch size too large %v", len(hashCh)) } } }(hashCh) } check := c.Bool("check") for { trxs, err := generateAccountTxs(it, accounts, tps) if err != nil { ilog.Errorf("generateAccountTxs error %v", err) continue } hashList, errList := it.SendTransactionN(trxs, false) ilog.Warnf("Send %v trxs, got %v hash, %v err", len(trxs), len(hashList), len(errList)) if check { expire := time.Now().Add(itest.Timeout) for _, hash := range hashList { select { case hashCh <- &hashItem{hash: hash, expire: expire}: case <-time.After(1 * time.Millisecond): } } } select { case <-sig: return fmt.Errorf("signal %v", sig) case <-ticker.C: } counter++ slotTotal += len(trxs) if counter == 10 { total += slotTotal currentTps := float64(slotTotal) / time.Now().Sub(slotStartTime).Seconds() averageTps := float64(total) / time.Now().Sub(startTime).Seconds() ilog.Warnf("Current tps %v, Average tps %v, Total tx %v", currentTps, averageTps, total) counter = 0 slotTotal = 0 slotStartTime = time.Now() } } }
BenchmarkAccountAction is the action of benchmark.
var BenchmarkAccountCommand = cli.Command{ Name: "benchmarkAccount", ShortName: "benchA", Usage: "Run account benchmark by given tps", Flags: BenchmarkAccountFlags, Action: BenchmarkAccountAction, }
BenchmarkAccountCommand is the subcommand for benchmark.
var BenchmarkAccountFlags = []cli.Flag{ cli.IntFlag{ Name: "tps", Value: 20, Usage: "The expected ratio of transactions per second", }, cli.BoolFlag{ Name: "check", Usage: "if check receipt", }, }
BenchmarkAccountFlags is the list of flags for benchmark.
var BenchmarkAction = func(c *cli.Context) error { it, err := itest.Load(c.GlobalString("keys"), c.GlobalString("config")) if err != nil { return err } txType := None cid := "" switch c.String("type") { case "t", "transfer": txType = TransferTx case "c", "contract": txType = ContractTransferTx contract, err := itest.LoadContract(c.GlobalString("code"), c.GlobalString("abi")) if err != nil { return err } cid, err = it.SetContract(contract) if err != nil { return err } case "g", "gas": txType = GasTx case "r", "ram": txType = RAMTx case "a", "account": txType = AccountTx err := it.Pledge(it.GetDefaultAccount(), "10000000", true) if err != nil { return err } itest.InitAmount = "10" itest.InitPledge = "20" itest.InitRAM = "1000" case "e", "exchange": txType = ExchangeTransferTx default: return fmt.Errorf("wrong transaction type: %v", txType) } accountFile := c.GlobalString("account") accounts, err := itest.LoadAccounts(accountFile) if err != nil { if err := AccountCaseAction(c); err != nil { return err } if accounts, err = itest.LoadAccounts(accountFile); err != nil { return err } } tps := c.Int("tps") memoSize := c.Int("memo") sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) startTime := time.Now() ticker := time.NewTicker(time.Second) counter := 0 total := 0 slotTotal := 0 slotStartTime := startTime for { num := 0 if txType == TransferTx { num, err = it.TransferN(tps, accounts, memoSize, false) } else if txType == ContractTransferTx { num, err = it.ContractTransferN(cid, tps, accounts, memoSize, false) } else if txType == GasTx { num, err = it.PledgeGasN("rand", tps, accounts, false) } else if txType == RAMTx { num, err = it.BuyRAMN("rand", tps, accounts, false) } else if txType == AccountTx { var accs []*itest.Account accs, err = it.CreateAccountN(tps, true, false) num = len(accs) } else if txType == ExchangeTransferTx { num, err = it.ExchangeTransferN(tps, accounts, memoSize, false) } else { panic("invalid tx type, check --type flag") } if err != nil { ilog.Infoln(err) } select { case <-sig: return itest.DumpAccounts(accounts, accountFile) case <-ticker.C: } counter++ slotTotal += num if counter == 10 { total += slotTotal currentTps := float64(slotTotal) / time.Now().Sub(slotStartTime).Seconds() averageTps := float64(total) / time.Now().Sub(startTime).Seconds() ilog.Warnf("Current tps %v, Average tps %v, Total tx %v", currentTps, averageTps, total) counter = 0 slotTotal = 0 slotStartTime = time.Now() } } }
BenchmarkAction is the action of benchmark.
var BenchmarkCommand = cli.Command{ Name: "benchmark", ShortName: "bench", Usage: "Run benchmark by given tps", Flags: BenchmarkFlags, Action: BenchmarkAction, }
BenchmarkCommand is the subcommand for benchmark.
var BenchmarkFlags = []cli.Flag{ cli.IntFlag{ Name: "tps", Value: 100, Usage: "The expected ratio of transactions per second", }, cli.StringFlag{ Name: "type", Value: "t", Usage: "The type of transaction, should be one of ['t'/'transfer', 'c'/'contract']", }, cli.IntFlag{ Name: "memo, m", Value: 0, Usage: "The size of a random memo message that would be contained in the transaction", }, }
BenchmarkFlags is the list of flags for benchmark.
var BenchmarkRPCAction = func(c *cli.Context) error { it, err := itest.Load(c.GlobalString("keys"), c.GlobalString("config")) if err != nil { return err } interval := c.Float64("interval") go loopCreateAccount(it, interval) go loopGetAccount(it, interval) go loopGetChainInfo(it, interval) go loopGetContract(it, interval) go loopGetGasRatio(it, interval) go loopGetNodeInfo(it, interval) go loopGetRAMInfo(it, interval) go loopGetStorage(it, interval) lastCount := 0 lastTime := time.Now() for { time.Sleep(time.Second) currentTps := float64(rpcCount-lastCount) / time.Now().Sub(lastTime).Seconds() ilog.Infof("Current tps %v", currentTps) lastCount = rpcCount lastTime = time.Now() } }
BenchmarkRPCAction is the action of benchmark.
var BenchmarkRPCCommand = cli.Command{ Name: "benchmark_rpc", ShortName: "bench_rpc", Usage: "Run benchmark rpc by given tps", Flags: BenchmarkRPCFlags, Action: BenchmarkRPCAction, }
BenchmarkRPCCommand is the subcommand for benchmark.
var BenchmarkRPCFlags = []cli.Flag{ cli.Float64Flag{ Name: "interval", Value: 0.2, Usage: "The interval (in second) between every call", }, }
BenchmarkRPCFlags is the list of flags for benchmark.
var BenchmarkSystemAction = func(c *cli.Context) error { itest.Interval = 1000 * time.Millisecond itest.InitAmount = "1000" itest.InitPledge = "1000" itest.InitRAM = "3000" logger := ilog.New() fileWriter := ilog.NewFileWriter(c.GlobalString("log")) fileWriter.SetLevel(ilog.LevelInfo) logger.AddWriter(fileWriter) ilog.InitLogger(logger) it, err := itest.Load(c.GlobalString("keys"), c.GlobalString("config")) if err != nil { return err } accountFile := c.GlobalString("account") accounts, err := itest.LoadAccounts(accountFile) if err != nil { if err := AccountCaseAction(c); err != nil { return err } if accounts, err = itest.LoadAccounts(accountFile); err != nil { return err } } accountMap := make(map[string]*itest.Account) for _, acc := range accounts { accountMap[acc.ID] = acc } tps := c.Int("tps") sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) startTime := time.Now() ticker := time.NewTicker(time.Second) counter := 0 total := 0 slotTotal := 0 slotStartTime := startTime code := ` class Test { init() {} hello() { return "world"; } can_update(data) { return blockchain.requireAuth(blockchain.contractOwner(), "active"); } }; module.exports = Test; ` ABI := ` { "lang": "javascript", "version": "1.0.0", "abi": [ {"name": "hello", "args": [], "amountLimit": [] }, {"name": "can_update", "args": ["string"], "amountLimit": [] } ] } ` contract, err := itest.NewContract(code, ABI) if err != nil { return err } checkReceiptConcurrent := 64 var contractMutex sync.Mutex contractList := make([]string, 0) contractMap := make(map[string]string) delayTxList := make([]string, 0) hashCh := make(chan *hashItem, 4*tps*int(itest.Timeout.Seconds())) for c := 0; c < checkReceiptConcurrent; c++ { go func(hashCh chan *hashItem) { counter := 0 failedCounter := 0 for item := range hashCh { client := it.GetClients()[rand.Intn(len(it.GetClients()))] _, err := client.CheckTransactionWithTimeout(item.hash, item.expire) counter++ if err != nil { ilog.Errorf("check transaction failed, %v", err) failedCounter++ } if counter%1000 == 0 { ilog.Warnf("check %v transaction, %v successful, %v failed.", counter, counter-failedCounter, failedCounter) } if len(hashCh) > 3*tps*int(itest.Timeout.Seconds()) { ilog.Infof("hash ch size too large %v", len(hashCh)) } } }(hashCh) } check := c.Bool("check") contractName := "system.empow" for { trxs := make([]*itest.Transaction, 0) errList := []error{} contractMutex.Lock() for num := 0; num < tps; num++ { tIndex := rand.Intn(5) var abiName string switch true { case tIndex <= 0 || len(contractList) == 0: abiName = setCode from := accounts[rand.Intn(len(accounts))] act0 := tx.NewAction("ram.empow", "buy", fmt.Sprintf(`["%v", "%v", %v]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 3000)) act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 100)) tx0 := itest.NewTransaction([]*tx.Action{act0, act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v"]`, contract)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { hash, err := it.SendTransaction(trx, true) if err != nil { errList = append(errList, err) } else { contractID := fmt.Sprintf("Contract%v", hash) contractList = append(contractList, contractID) contractMap[contractID] = from.ID } } break case tIndex <= 1: abiName = updateCode contractID := contractList[rand.Intn(len(contractList))] owner := accountMap[contractMap[contractID]] act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", owner.ID, 100)) tx0 := itest.NewTransaction([]*tx.Action{act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } contract.ID = contractID act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", ""]`, contract)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = owner.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break case tIndex <= 2: abiName = cancelDelaytx if len(delayTxList) == 0 { from := accounts[rand.Intn(len(accounts))] act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act1}) tx0.Delay = 90 * 1e9 trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { hash, err := it.SendTransaction(trx, false) if err != nil { errList = append(errList, err) } else { delayTxList = append(delayTxList, hash) } } } else { ilog.Infof("cancel delay tx") act1 := tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v"]`, delayTxList[0])) delayTxList = delayTxList[1:] tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err := it.GetDefaultAccount().Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } } break case tIndex <= 3: abiName = receipt from := accounts[rand.Intn(len(accounts))] act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v"]`, from.ID)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break case tIndex <= 4: abiName = requireAuth from := accounts[rand.Intn(len(accounts))] act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "owner"]`, from.ID)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break } } contractMutex.Unlock() hashList, tmpList := it.SendTransactionN(trxs, false) errList = append(errList, tmpList...) ilog.Warnf("Send %v trxs, got %v hash, %v err", len(trxs), len(hashList), len(errList)) if check { expire := time.Now().Add(itest.Timeout) for _, hash := range hashList { select { case hashCh <- &hashItem{hash: hash, expire: expire}: case <-time.After(1 * time.Millisecond): } } } select { case <-sig: return fmt.Errorf("signal %v", sig) case <-ticker.C: } counter++ slotTotal += len(trxs) if counter == 10 { total += slotTotal currentTps := float64(slotTotal) / time.Now().Sub(slotStartTime).Seconds() averageTps := float64(total) / time.Now().Sub(startTime).Seconds() ilog.Warnf("Current tps %v, Average tps %v, Total tx %v, contractNum %v, delaytxNum %v", currentTps, averageTps, total, len(contractList), len(delayTxList)) counter = 0 slotTotal = 0 slotStartTime = time.Now() } } }
BenchmarkSystemAction is the action of benchmark.
var BenchmarkSystemCommand = cli.Command{ Name: "benchmarkSystem", ShortName: "benchS", Usage: "Run system benchmark by given tps", Flags: BenchmarkSystemFlags, Action: BenchmarkSystemAction, }
BenchmarkSystemCommand is the subcommand for benchmark system.empow.
var BenchmarkSystemFlags = []cli.Flag{ cli.IntFlag{ Name: "tps", Value: 50, Usage: "The expected ratio of transactions per second", }, cli.BoolFlag{ Name: "check", Usage: "if check receipt", }, }
BenchmarkSystemFlags is the list of flags for benchmark.
var BenchmarkToken721Action = func(c *cli.Context) error { itest.Interval = 1000 * time.Millisecond itest.InitAmount = "1000" itest.InitPledge = "1000" itest.InitRAM = "3000" logger := ilog.New() fileWriter := ilog.NewFileWriter(c.GlobalString("log")) fileWriter.SetLevel(ilog.LevelInfo) logger.AddWriter(fileWriter) ilog.InitLogger(logger) it, err := itest.Load(c.GlobalString("keys"), c.GlobalString("config")) if err != nil { return err } accountFile := c.GlobalString("account") accounts, err := itest.LoadAccounts(accountFile) if err != nil { if err := AccountCaseAction(c); err != nil { return err } if accounts, err = itest.LoadAccounts(accountFile); err != nil { return err } } accountMap := make(map[string]*itest.Account) for _, acc := range accounts { accountMap[acc.ID] = acc } tps := c.Int("tps") sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) startTime := time.Now() ticker := time.NewTicker(time.Second) counter := 0 total := 0 slotTotal := 0 slotStartTime := startTime issueNumber := 5 checkReceiptConcurrent := 64 tokenList := []string{} tokenMap := make(map[string]*token721Info) tokenPrefix := "t" + strconv.FormatInt(time.Now().UnixNano(), 10)[14:] tokenOffset := 0 var tokenMutex sync.Mutex hashCh := make(chan *hashItem, 4*tps*int(itest.Timeout.Seconds())) for c := 0; c < checkReceiptConcurrent; c++ { go func(hashCh chan *hashItem) { counter := 0 failedCounter := 0 for item := range hashCh { client := it.GetClients()[rand.Intn(len(it.GetClients()))] r, err := client.CheckTransactionWithTimeout(item.hash, item.expire) ilog.Debugf("receipt: %v", r) counter++ if err != nil { ilog.Errorf("check transaction failed, %v", err) failedCounter++ } else { for i := 0; i < len(r.Receipts); i++ { if r.Receipts[i].FuncName == "token721.empow/issue" { args := make([]string, 3) err := json.Unmarshal([]byte(r.Receipts[i].Content), &args) if err != nil { continue } ilog.Debugf("got receipt %v %v", r.Receipts[i], args) tokenMutex.Lock() tokenSym := args[0] acc := args[1] for j := 0; j < len(r.Returns); j++ { ret := r.Returns[j] ret = ret[2:(len(ret) - 2)] if _, ok := tokenMap[tokenSym].balance[acc]; !ok { tokenMap[tokenSym].balance[acc] = make([]string, 0) tokenMap[tokenSym].acclist = append(tokenMap[tokenSym].acclist, acc) } tokenMap[tokenSym].balance[acc] = append(tokenMap[tokenSym].balance[acc], ret) retn, _ := strconv.ParseInt(ret, 10, 32) tokenMap[tokenSym].supply = int(math.Max(float64(tokenMap[tokenSym].supply), float64(retn))) } tokenMutex.Unlock() break } else if r.Receipts[i].FuncName == "token721.empow/create" { args := make([]interface{}, 3) err := json.Unmarshal([]byte(r.Receipts[i].Content), &args) if err != nil { continue } ilog.Debugf("got receipt %v %v", r.Receipts[i], args) tokenMutex.Lock() tokenSym := args[0].(string) issuer := args[1].(string) tokenList = append(tokenList, tokenSym) tokenMap[tokenSym] = &token721Info{ sym: tokenSym, issuer: issuer, balance: make(map[string][]string), acclist: []string{}, supply: 0, } tokenMutex.Unlock() break } } } if counter%1000 == 0 { ilog.Warnf("check %v transaction, %v successful, %v failed. channel size %v", counter, counter-failedCounter, failedCounter, len(hashCh)) } if len(hashCh) > 3*tps*int(itest.Timeout.Seconds()) { ilog.Infof("hash ch size too large %v", len(hashCh)) } } }(hashCh) } check := c.Bool("check") contractName := "token721.empow" for { trxs := make([]*itest.Transaction, 0) errList := []error{} tokenMutex.Lock() for num := 0; num < tps; num++ { tIndex := rand.Intn(2400) var abiName string switch true { case tIndex <= 0 || len(tokenList) < 5: abiName = createToken721 tokenSym := tokenPrefix + strconv.FormatInt(int64(tokenOffset), 10) tokenOffset++ from := accounts[rand.Intn(len(accounts))] act0 := tx.NewAction("ram.empow", "buy", fmt.Sprintf(`["%v", "%v", %v]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 1000)) act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act0, act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "%v", %v]`, tokenSym, from.ID, 100000000000)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break case tIndex <= 1000 || len(tokenMap[tokenList[0]].balance) < 10: abiName = issueToken721 tokenSym := tokenList[rand.Intn(len(tokenList))] if len(tokenMap[tokenList[0]].balance) < 10 { tokenSym = tokenList[0] } issuer := accountMap[tokenMap[tokenSym].issuer] to := accounts[rand.Intn(len(accounts))] act0 := tx.NewAction("ram.empow", "buy", fmt.Sprintf(`["%v", "%v", %v]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", issuer.ID, 1000)) act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", issuer.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act0, act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } acts := []*tx.Action{} for i := 0; i < issueNumber; i++ { acts = append(acts, tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "%v", "%v"]`, tokenSym, to.ID, "meta"+to.ID))) } tx1 := itest.NewTransaction(acts) trx, err = issuer.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break case tIndex <= 2000: abiName = transferToken721 tokenSym := tokenList[rand.Intn(len(tokenList))] if len(tokenMap[tokenSym].balance) == 0 { tokenSym = tokenList[0] } var from *itest.Account var tokenID string for k, v := range tokenMap[tokenSym].balance { from = accountMap[k] tokenID = v[0] break } to := accounts[rand.Intn(len(accounts))] act0 := tx.NewAction("ram.empow", "buy", fmt.Sprintf(`["%v", "%v", %v]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 1000)) act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act0, act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "%v", "%v", "%v"]`, tokenSym, from.ID, to.ID, tokenID)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) tokenMap[tokenSym].balance[from.ID] = tokenMap[tokenSym].balance[from.ID][1:] if len(tokenMap[tokenSym].balance[from.ID]) == 0 { delete(tokenMap[tokenSym].balance, from.ID) } } break case tIndex <= 2100: abiName = balanceOfToken721 tokenSym := tokenList[rand.Intn(len(tokenList))] if len(tokenMap[tokenSym].balance) == 0 { tokenSym = tokenList[0] } from := accountMap[tokenMap[tokenSym].acclist[rand.Intn(len(tokenMap[tokenSym].acclist))]] act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "%v"]`, tokenSym, from.ID)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break case tIndex <= 2200: abiName = ownerOfToken721 tokenSym := tokenList[rand.Intn(len(tokenList))] if tokenMap[tokenSym].supply == 0 { tokenSym = tokenList[0] } from := accounts[rand.Intn(len(accounts))] tokenID := rand.Intn(tokenMap[tokenSym].supply) act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "%v"]`, tokenSym, tokenID)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break case tIndex <= 2300: abiName = tokenOfOwnerToken721 tokenSym := tokenList[rand.Intn(len(tokenList))] if len(tokenMap[tokenSym].balance) == 0 { tokenSym = tokenList[0] } var from *itest.Account var idx int for k, v := range tokenMap[tokenSym].balance { from = accountMap[k] idx = rand.Intn(len(v)) break } act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "%v", %v]`, tokenSym, from.ID, idx)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break case tIndex <= 2400: abiName = tokenMetadataToken721 tokenSym := tokenList[rand.Intn(len(tokenList))] if tokenMap[tokenSym].supply == 0 { tokenSym = tokenList[0] } from := accounts[rand.Intn(len(accounts))] tokenID := rand.Intn(tokenMap[tokenSym].supply) act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "%v"]`, tokenSym, tokenID)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break } } tokenMutex.Unlock() hashList, tmpList := it.SendTransactionN(trxs, false) errList = append(errList, tmpList...) ilog.Warnf("Send %v trxs, got %v hash, %v err", len(trxs), len(hashList), len(errList)) if check { expire := time.Now().Add(itest.Timeout) for _, hash := range hashList { select { case hashCh <- &hashItem{hash: hash, expire: expire}: case <-time.After(1 * time.Millisecond): } } } select { case <-sig: return fmt.Errorf("signal %v", sig) case <-ticker.C: } counter++ slotTotal += len(trxs) if counter == 10 { total += slotTotal currentTps := float64(slotTotal) / time.Now().Sub(slotStartTime).Seconds() averageTps := float64(total) / time.Now().Sub(startTime).Seconds() ilog.Warnf("Current tps %v, Average tps %v, Total tx %v, token num %v", currentTps, averageTps, total, len(tokenList)) counter = 0 slotTotal = 0 slotStartTime = time.Now() } } }
BenchmarkToken721Action is the action of benchmark.
var BenchmarkToken721Command = cli.Command{ Name: "benchmarkToken721", ShortName: "benchT721", Usage: "Run token benchmark by given tps", Flags: BenchmarkToken721Flags, Action: BenchmarkToken721Action, }
BenchmarkToken721Command is the subcommand for benchmark.
var BenchmarkToken721Flags = []cli.Flag{ cli.IntFlag{ Name: "tps", Value: 100, Usage: "The expected ratio of transactions per second", }, cli.BoolFlag{ Name: "check", Usage: "if check receipt", }, }
BenchmarkToken721Flags is the list of flags for benchmark.
var BenchmarkTokenAction = func(c *cli.Context) error { itest.Interval = 1000 * time.Millisecond itest.InitAmount = "1000" itest.InitPledge = "1000" itest.InitRAM = "3000" logger := ilog.New() fileWriter := ilog.NewFileWriter(c.GlobalString("log")) fileWriter.SetLevel(ilog.LevelInfo) logger.AddWriter(fileWriter) ilog.InitLogger(logger) it, err := itest.Load(c.GlobalString("keys"), c.GlobalString("config")) if err != nil { return err } accountFile := c.GlobalString("account") t0 := time.Now() accounts, err := itest.LoadAccounts(accountFile) if err != nil { if err := AccountCaseAction(c); err != nil { return err } if accounts, err = itest.LoadAccounts(accountFile); err != nil { return err } } t1 := time.Now() ilog.Warnf("load account time: %v, got %v", float64(t1.UnixNano()-t0.UnixNano())/1e9, len(accounts)) accountMap := make(map[string]*itest.Account) for _, acc := range accounts { accountMap[acc.ID] = acc } tps := c.Int("tps") sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) startTime := time.Now() ticker := time.NewTicker(time.Second) counter := 0 total := 0 slotTotal := 0 slotStartTime := startTime tokenList := []string{"em"} tokenMap := make(map[string]*tokenInfo) tokenMap["em"] = &tokenInfo{ sym: "em", issuer: "", balance: make(map[string]float64), acclist: make([]string, 0), } for _, acc := range accounts { tokenMap["em"].balance[acc.ID] = acc.Balance() tokenMap["em"].acclist = append(tokenMap["em"].acclist, acc.ID) } tokenPrefix := "t" + strconv.FormatInt(time.Now().UnixNano(), 10)[14:] checkReceiptConcurrent := 64 tokenOffset := 0 var tokenMutex sync.Mutex hashCh := make(chan *hashItem, 4*tps*int(itest.Timeout.Seconds())) for c := 0; c < checkReceiptConcurrent; c++ { go func(hashCh chan *hashItem) { counter := 0 failedCounter := 0 for item := range hashCh { client := it.GetClients()[rand.Intn(len(it.GetClients()))] r, err := client.CheckTransactionWithTimeout(item.hash, item.expire) counter++ if err != nil { ilog.Errorf("check transaction failed, %v", err) failedCounter++ } else { for i := 0; i < len(r.Receipts); i++ { if r.Receipts[i].FuncName == "token.empow/issue" { args := make([]string, 3) err := json.Unmarshal([]byte(r.Receipts[i].Content), &args) if err != nil { continue } ilog.Debugf("got receipt %v %v", r.Receipts[i], args) tokenMutex.Lock() tokenSym := args[0] if !strings.HasPrefix(tokenSym, tokenPrefix) { tokenMutex.Unlock() continue } acc := args[1] amountStr := args[2] amount, _ := strconv.ParseFloat(amountStr, 32) if _, ok := tokenMap[tokenSym].balance[acc]; !ok { tokenMap[tokenSym].acclist = append(tokenMap[tokenSym].acclist, acc) } tokenMap[tokenSym].balance[acc] += amount tokenMutex.Unlock() break } else if r.Receipts[i].FuncName == "token.empow/create" { args := make([]interface{}, 4) err := json.Unmarshal([]byte(r.Receipts[i].Content), &args) if err != nil { continue } ilog.Debugf("got receipt %v %v", r.Receipts[i], args) tokenMutex.Lock() tokenSym := args[0].(string) issuer := args[1].(string) tokenList = append(tokenList, tokenSym) tokenMap[tokenSym] = &tokenInfo{ sym: tokenSym, issuer: issuer, balance: make(map[string]float64), acclist: []string{}, } tokenMutex.Unlock() break } } } if counter%1000 == 0 { ilog.Warnf("check %v transaction, %v successful, %v failed.", counter, counter-failedCounter, failedCounter) } if len(hashCh) > 3*tps*int(itest.Timeout.Seconds()) { ilog.Infof("hash ch size too large %v", len(hashCh)) } } }(hashCh) } check := c.Bool("check") contractName := "token.empow" for { trxs := make([]*itest.Transaction, 0) errList := []error{} tokenMutex.Lock() for num := 0; num < tps; num++ { tIndex := rand.Intn(10000) var abiName string switch true { case tIndex <= 0 || len(tokenList) < 5: abiName = createToken tokenSym := tokenPrefix + strconv.FormatInt(int64(tokenOffset), 10) tokenOffset++ from := accounts[rand.Intn(len(accounts))] decimal := rand.Intn(5) + 2 act0 := tx.NewAction("ram.empow", "buy", fmt.Sprintf(`["%v", "%v", %v]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10000)) act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act0, act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "%v", %v, %v]`, tokenSym, from.ID, 100000000000, fmt.Sprintf(`{"decimal": %v}`, decimal))) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break case tIndex <= 10: abiName = supplyToken ilog.Infof("supply") tokenSym := tokenList[rand.Intn(len(tokenList))] from := accounts[rand.Intn(len(accounts))] act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v"]`, tokenSym)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break case tIndex <= 20: abiName = totalSupplyToken ilog.Infof("total supply") tokenSym := tokenList[rand.Intn(len(tokenList))] from := accounts[rand.Intn(len(accounts))] act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v"]`, tokenSym)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break case tIndex <= 120: abiName = balanceOfToken tokenSym := tokenList[rand.Intn(len(tokenList))] from := accounts[rand.Intn(len(accounts))] act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "%v"]`, tokenSym, from.ID)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break case tIndex <= 220: abiName = destroyToken tokenSym := tokenList[rand.Intn(len(tokenList))] if len(tokenMap[tokenSym].balance) == 0 { tokenSym = "em" } from := accountMap[tokenMap[tokenSym].acclist[rand.Intn(len(tokenMap[tokenSym].acclist))]] balance := tokenMap[tokenSym].balance[from.ID] act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } amount := math.Max(float64(rand.Intn(int(math.Max(balance, 1))))/100.0, 0.01) act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "%v", "%v"]`, tokenSym, from.ID, amount)) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) tokenMap[tokenSym].balance[from.ID] -= amount } break case tIndex <= 1000: abiName = issueToken if len(tokenList) == 1 { break } tokenSym := tokenList[1+rand.Intn(len(tokenList)-1)] issuer := accountMap[tokenMap[tokenSym].issuer] to := accounts[rand.Intn(len(accounts))] act0 := tx.NewAction("ram.empow", "buy", fmt.Sprintf(`["%v", "%v", %v]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", issuer.ID, 1000)) act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", issuer.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act0, act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } amount := 1000 + 1000*rand.Float64() act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "%v", "%v"]`, tokenSym, to.ID, int64(amount))) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = issuer.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } break case tIndex <= 1100: abiName = transferFreezeToken tokenSym := tokenList[rand.Intn(len(tokenList))] if len(tokenMap[tokenSym].balance) == 0 { tokenSym = "em" } from := accountMap[tokenMap[tokenSym].acclist[rand.Intn(len(tokenMap[tokenSym].acclist))]] to := accounts[rand.Intn(len(accounts))] balance := tokenMap[tokenSym].balance[from.ID] act0 := tx.NewAction("ram.empow", "buy", fmt.Sprintf(`["%v", "%v", %v]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10000)) act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act0, act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } ftime := time.Now().UnixNano() + int64(rand.Intn(100))*1e9 amount := math.Max(float64(rand.Intn(int(math.Max(balance, 1))))/100.0, 0.01) act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "%v", "%v", "%v", %v, "%v"]`, tokenSym, from.ID, to.ID, amount, ftime, "")) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) tokenMap[tokenSym].balance[from.ID] -= amount } break default: abiName = transferToken tokenSym := tokenList[rand.Intn(len(tokenList))] if len(tokenMap[tokenSym].balance) == 0 { tokenSym = "em" } from := accountMap[tokenMap[tokenSym].acclist[rand.Intn(len(tokenMap[tokenSym].acclist))]] to := accounts[rand.Intn(len(accounts))] balance := tokenMap[tokenSym].balance[from.ID] act0 := tx.NewAction("ram.empow", "buy", fmt.Sprintf(`["%v", "%v", %v]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 100)) act1 := tx.NewAction("gas.empow", "pledge", fmt.Sprintf(`["%v", "%v", "%v"]`, "EM2ZsSw7RWYC229Z1ib7ujKhken9GFR7dBkTTEbBWMKeLpVas", from.ID, 10)) tx0 := itest.NewTransaction([]*tx.Action{act0, act1}) trx, err := it.GetDefaultAccount().Sign(tx0) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) } amount := math.Max(float64(rand.Intn(int(math.Max(balance, 1))))/100.0, 0.01) act1 = tx.NewAction(contractName, abiName, fmt.Sprintf(`["%v", "%v", "%v", "%v", "%v"]`, tokenSym, from.ID, to.ID, amount, "")) tx1 := itest.NewTransaction([]*tx.Action{act1}) trx, err = from.Sign(tx1) if err != nil { errList = append(errList, err) } else { trxs = append(trxs, trx) tokenMap[tokenSym].balance[from.ID] -= amount } break } } tokenMutex.Unlock() hashList, tmpList := it.SendTransactionN(trxs, false) errList = append(errList, tmpList...) ilog.Warnf("Send %v trxs, got %v hash, %v err", len(trxs), len(hashList), len(errList)) if check { expire := time.Now().Add(itest.Timeout) for _, hash := range hashList { select { case hashCh <- &hashItem{hash: hash, expire: expire}: case <-time.After(1 * time.Millisecond): } } } select { case <-sig: return fmt.Errorf("signal %v", sig) case <-ticker.C: } counter++ slotTotal += len(trxs) if counter == 10 { total += slotTotal currentTps := float64(slotTotal) / time.Now().Sub(slotStartTime).Seconds() averageTps := float64(total) / time.Now().Sub(startTime).Seconds() ilog.Warnf("Current tps %v, Average tps %v, Total tx %v, token num %v", currentTps, averageTps, total, len(tokenList)) counter = 0 slotTotal = 0 slotStartTime = time.Now() } } }
BenchmarkTokenAction is the action of benchmark.
var BenchmarkTokenCommand = cli.Command{ Name: "benchmarkToken", ShortName: "benchT", Usage: "Run token benchmark by given tps", Flags: BenchmarkTokenFlags, Action: BenchmarkTokenAction, }
BenchmarkTokenCommand is the subcommand for benchmark.
var BenchmarkTokenFlags = []cli.Flag{ cli.IntFlag{ Name: "tps", Value: 50, Usage: "The expected ratio of transactions per second", }, cli.BoolFlag{ Name: "check", Usage: "if check receipt", }, }
BenchmarkTokenFlags is the list of flags for benchmark.
var BonusCaseAction = func(c *cli.Context) error { acc := c.GlobalString("aname") keysfile := c.GlobalString("keys") configfile := c.GlobalString("config") it, err := itest.Load(keysfile, configfile) if err != nil { return err } data, _, number, err := it.GetContractStorage("token.empow", "TB"+acc, "contribute") if err != nil { return err } ilog.Debugf("%v contribute = %v, number = %v", acc, data, number) contribute, err := strconv.ParseInt(data, 10, 64) if err != nil { return err } data1, _, _, err := it.GetContractStorage("bonus.empow", "blockContrib", "") if err != nil { return err } ratef, err := strconv.ParseFloat(strings.Trim(data1, "\""), 64) if err != nil { return err } cnt, err := countBlockProducedBy(it, acc, number) if cnt == 0 || err != nil { return err } rate := int64(ratef * 1e8) if contribute == cnt*rate { ilog.Infof("success: contribute = %v, cnt*rate = %v", contribute, cnt*rate) return nil } else if contribute < cnt*rate && contribute*103 > cnt*rate*100 { ilog.Infof("success contribute is nearly equal to cnt*rate: contribute = %v, cnt*rate = %v", contribute, cnt*rate) return nil } return fmt.Errorf("check contribute failed: contribute = %v, cnt = %v, rate = %v(%v)", contribute, cnt, rate, data1) }
BonusCaseAction is the action of Bonus test case
var BonusCaseCommand = cli.Command{ Name: "bonus_case", ShortName: "b_case", Usage: "run bonus test case", Action: BonusCaseAction, }
BonusCaseCommand is the command of account test case
var Command = cli.Command{ Name: "run", Usage: "run test by benchmark data", Flags: Flags, Subcommands: []cli.Command{ AccountCaseCommand, AccountRoundCommand, TransferCaseCommand, ContractCaseCommand, CommonVoteCaseCommand, VoteCaseCommand, VoteNodeCaseCommand, BonusCaseCommand, BenchmarkCommand, BenchmarkTokenCommand, BenchmarkToken721Command, BenchmarkSystemCommand, BenchmarkAccountCommand, BenchmarkRPCCommand, }, }
Command is the command of run
var CommonVoteCaseAction = func(c *cli.Context) error { afile := c.String("account") keysfile := c.GlobalString("keys") configfile := c.GlobalString("newVoteConfig") it, err := itest.Load(keysfile, configfile) if err != nil { return err } client := it.GetClients()[0] accounts, err := itest.LoadAccounts(afile) if err != nil { return err } newVoteConfig := make(map[string]interface{}) newVoteConfig["resultNumber"] = 2 newVoteConfig["minVote"] = 10 newVoteConfig["options"] = []string{"option1", "option2", "option3", "option4"} newVoteConfig["anyOption"] = false newVoteConfig["freezeTime"] = 0 bank := it.GetDefaultAccount() hash, err := it.CallActionWithRandClient(it.GetDefaultAccount(), "vote.empow", "newVote", bank.ID, "test vote", newVoteConfig) if err != nil { return err } receipt, err := client.GetReceipt(hash) if err != nil { return err } js, err := simplejson.NewJson([]byte(receipt.Returns[0])) if err != nil { return err } voteID, err := js.GetIndex(0).String() if err != nil { return err } fmt.Println("vote id is", voteID) allArgs := make([][]interface{}, 0) allArgs = append(allArgs, []interface{}{voteID, accounts[1].ID, "option3", "5"}) allArgs = append(allArgs, []interface{}{voteID, accounts[1].ID, "option3", "5"}) allArgs = append(allArgs, []interface{}{voteID, accounts[1].ID, "option1", "20"}) allArgs = append(allArgs, []interface{}{voteID, accounts[0].ID, "option3", "100"}) var callingAccounts = []*itest.Account{accounts[1], accounts[1], accounts[1], accounts[0]} res := make(chan interface{}) go func() { for idx := range allArgs { go func(i int, res chan interface{}) { _, err := it.CallActionWithRandClient(callingAccounts[i], "vote.empow", "vote", allArgs[i]...) res <- err }(idx, res) } }() for range allArgs { switch value := (<-res).(type) { case error: return value.(error) } } checkReturn := func(actionName string, expected string, args ...interface{}) error { hash, err := client.CallAction(true, bank, "vote.empow", actionName, args...) if err != nil { return err } receipt, err = client.GetReceipt(hash) if err != nil { return err } js, err := simplejson.NewJson([]byte(receipt.Returns[0])) if err != nil { return err } result, err := js.GetIndex(0).String() if err != nil { return err } if result != expected { return fmt.Errorf("invalid return %v, expect %v", result, expected) } return nil } res2 := make(chan error) go func() { res2 <- checkReturn("getResult", `[{"option":"option3","votes":"110"},{"option":"option1","votes":"20"}]`, voteID) }() go func() { res2 <- checkReturn("getOption", `{"votes":"110","deleted":false,"clearTime":-1}`, voteID, "option3") }() for i := 0; i < 2; i++ { if err := <-res2; err != nil { return err } } return nil }
CommonVoteCaseAction is the action of vote test case
var CommonVoteCaseCommand = cli.Command{ Name: "common_vote_case", ShortName: "cv_case", Usage: "run common VoteProducer test case", Flags: CommonVoteCaseFlags, Action: CommonVoteCaseAction, }
CommonVoteCaseCommand is the command of common vote test case
var CommonVoteCaseFlags = []cli.Flag{ cli.StringFlag{ Name: "account, a", Value: "accounts.json", Usage: "load accounts from `FILE`", }, }
CommonVoteCaseFlags is the flags of vote test case
var ContractCaseAction = func(c *cli.Context) error { afile := c.String("account") output := c.String("output") tnum := c.Int("number") keysfile := c.GlobalString("keys") configfile := c.GlobalString("config") codefile := c.GlobalString("code") abifile := c.GlobalString("abi") memoSize := c.Int("memo") it, err := itest.Load(keysfile, configfile) if err != nil { return err } contract, err := itest.LoadContract(codefile, abifile) if err != nil { return err } accounts, err := itest.LoadAccounts(afile) if err != nil { return err } cid, err := it.SetContract(contract) if err != nil { return err } if _, err := it.ContractTransferN(cid, tnum, accounts, memoSize, true); err != nil { return err } if err := it.CheckAccounts(accounts); err != nil { return err } if err := itest.DumpAccounts(accounts, output); err != nil { return err } return nil }
ContractCaseAction is the action of contract test case
var ContractCaseCommand = cli.Command{ Name: "contract_case", ShortName: "c_case", Usage: "run contract test case", Flags: ContractCaseFlags, Action: ContractCaseAction, }
ContractCaseCommand is the command of contract test case
var ContractCaseFlags = []cli.Flag{ cli.IntFlag{ Name: "number, n", Value: 1000, Usage: "number of transaction", }, cli.StringFlag{ Name: "account, a", Value: "accounts.json", Usage: "load accounts from `FILE`", }, cli.StringFlag{ Name: "output, o", Value: "accounts.json", Usage: "output of account information", }, cli.IntFlag{ Name: "memo, m", Value: 0, Usage: "The size of a random memo message that would be contained in the transaction", }, }
ContractCaseFlags ...
var Flags = []cli.Flag{ cli.StringFlag{ Name: "keys, k", Value: "", Usage: "Load keys from `FILE`", }, cli.StringFlag{ Name: "config, c", Value: "", Usage: "Load itest configuration from `FILE`", }, cli.StringFlag{ Name: "code", Value: "", Usage: "Load contract code from `FILE`", }, cli.StringFlag{ Name: "abi", Value: "", Usage: "Load contract abi from `FILE`", }, cli.StringFlag{ Name: "account, a", Value: "accounts.json", Usage: "The account file that itest would load from if exists", }, cli.IntFlag{ Name: "anum", Value: 100, Usage: "The number of accounts to generated if no given account file", }, cli.StringFlag{ Name: "aname", Value: "EM2ZsSi4y3AYqvhbfyzHwDKShtpiNpCQK4WsgTgavup51N2UB", Usage: "The account name to check/run actions", }, cli.StringFlag{ Name: "log, l", Value: "itest_logs", Usage: "log file path", }, }
Flags is the flags of run command
var TransferCaseAction = func(c *cli.Context) error { afile := c.GlobalString("account") output := c.String("output") tnum := c.Int("number") keysfile := c.GlobalString("keys") configfile := c.GlobalString("config") memoSize := c.Int("memo") it, err := itest.Load(keysfile, configfile) if err != nil { return err } accounts, err := itest.LoadAccounts(afile) if err != nil { return err } if _, err := it.TransferN(tnum, accounts, memoSize, true); err != nil { return err } if err := it.CheckAccounts(accounts); err != nil { return err } if err := itest.DumpAccounts(accounts, output); err != nil { return err } return nil }
TransferCaseAction is the action of transfer test case
var TransferCaseCommand = cli.Command{ Name: "transfer_case", ShortName: "t_case", Usage: "run transfer test case", Flags: TransferCaseFlags, Action: TransferCaseAction, }
TransferCaseCommand is the command of transfer test case
var TransferCaseFlags = []cli.Flag{ cli.IntFlag{ Name: "number, n", Value: 1000, Usage: "number of transaction", }, cli.StringFlag{ Name: "output, o", Value: "accounts.json", Usage: "output of account information", }, cli.IntFlag{ Name: "memo, m", Value: 0, Usage: "The size of a random memo message that would be contained in the transaction", }, }
TransferCaseFlags is the flags of transfer test case
var VoteCaseAction = func(c *cli.Context) error { afile := c.String("account") output := c.String("output") tnum := c.Int("number") punm := c.Int("pnumber") keysfile := c.GlobalString("keys") configfile := c.GlobalString("config") it, err := itest.Load(keysfile, configfile) if err != nil { return err } accounts, err := itest.LoadAccounts(afile) if err != nil { return err } if err := it.VoteN(tnum, punm, accounts); err != nil { return err } if err := it.CheckAccounts(accounts); err != nil { return err } if err := itest.DumpAccounts(accounts, output); err != nil { return err } return nil }
VoteCaseAction is the action of vote test case
var VoteCaseCommand = cli.Command{ Name: "vote_case", ShortName: "v_case", Usage: "run VoteProducer test case", Flags: VoteCaseFlags, Action: VoteCaseAction, }
VoteCaseCommand is the command of vote test case
var VoteCaseFlags = []cli.Flag{ cli.IntFlag{ Name: "number, n", Value: 1000, Usage: "number of transaction", }, cli.IntFlag{ Name: "pnumber, pn", Value: 1, Usage: "number of producer", }, cli.StringFlag{ Name: "account, a", Value: "accounts.json", Usage: "load accounts from `FILE`", }, cli.StringFlag{ Name: "output, o", Value: "accounts.json", Usage: "output of account information", }, }
VoteCaseFlags is the flags of vote test case
var VoteNodeCaseAction = func(c *cli.Context) error { tnum := c.Int("number") unvote := c.Bool("unvote") keysfile := c.GlobalString("keys") configfile := c.GlobalString("config") afile := c.GlobalString("account") it, err := itest.Load(keysfile, configfile) if err != nil { return err } accounts, err := itest.LoadAccounts(afile) if err != nil { return err } if unvote { if err := it.CancelVoteNode(tnum, accounts); err != nil { return err } } else { if err := it.VoteNode(tnum, accounts); err != nil { return err } } return nil }
VoteNodeCaseAction is the action of vote test case
var VoteNodeCaseCommand = cli.Command{ Name: "vote_node_case", ShortName: "n_case", Usage: "run a test to vote or unvote for node", Flags: VoteNodeCaseFlags, Action: VoteNodeCaseAction, }
VoteNodeCaseCommand is vote or unvote for the test of the authentication node
var VoteNodeCaseFlags = []cli.Flag{ cli.IntFlag{ Name: "number, n", Value: 0, Usage: "number of vote", }, cli.BoolFlag{ Name: "unvote, u", Usage: "Cancel vote based on configuration file", }, }
VoteNodeCaseFlags is the flags of vote test case
Functions ¶
This section is empty.
Types ¶
This section is empty.