github.com/turingchain2020/turingchain@v1.1.21/cmd/autotest/types/utils.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package types
     6  
     7  import (
     8  	"encoding/json"
     9  	"errors"
    10  	"fmt"
    11  	"os/exec"
    12  	"strconv"
    13  	"strings"
    14  
    15  	"github.com/turingchain2020/turingchain/common/log/log15"
    16  )
    17  
    18  //FloatDiff const
    19  const FloatDiff = 0.00001
    20  
    21  //AutoTestLogFormat customize log15 log format
    22  func AutoTestLogFormat() log15.Format {
    23  
    24  	logfmt := log15.LogfmtFormat()
    25  
    26  	return log15.FormatFunc(func(r *log15.Record) []byte {
    27  
    28  		if r.Msg == "PrettyJsonLogFormat" && len(r.Ctx) == 4 {
    29  
    30  			b, ok := r.Ctx[3].([]byte)
    31  			if ok {
    32  				//return raw json data directly
    33  				return b
    34  			}
    35  		}
    36  
    37  		return logfmt.Format(r)
    38  	})
    39  
    40  }
    41  
    42  //RunTuringchainCli invoke turingchain client
    43  func RunTuringchainCli(para []string) (string, error) {
    44  
    45  	rawOut, err := exec.Command(CliCmd, para[0:]...).CombinedOutput()
    46  
    47  	strOut := string(rawOut)
    48  
    49  	return strOut, err
    50  }
    51  
    52  //IsBalanceEqualFloat according to the accuracy of coins balance
    53  func IsBalanceEqualFloat(f1 float64, f2 float64) bool {
    54  
    55  	if (f2-f1 < FloatDiff) && (f1-f2 < FloatDiff) {
    56  		return true
    57  	}
    58  
    59  	return false
    60  }
    61  
    62  func checkTxHashValid(txHash string) bool {
    63  
    64  	return len(txHash) == 66 && strings.HasPrefix(txHash, "0x")
    65  }
    66  
    67  //SendTxCommand excute
    68  func SendTxCommand(cmd string) (string, bool) {
    69  
    70  	output, err := RunTuringchainCli(strings.Fields(cmd))
    71  	if err != nil {
    72  		return err.Error(), false
    73  	} else if len(output) == 67 {
    74  		output = output[0 : len(output)-1]
    75  	} else {
    76  
    77  		//check if privacy transaction
    78  		var jsonMap map[string]interface{}
    79  		err = json.Unmarshal([]byte(output), &jsonMap)
    80  		if err != nil {
    81  			return output, false
    82  		}
    83  		if hash, ok := jsonMap["hash"].(string); ok {
    84  			output = hash
    85  		}
    86  	}
    87  
    88  	return output, checkTxHashValid(output)
    89  }
    90  
    91  //SendPrivacyTxCommand 隐私交易执行回执哈希为json格式,需要解析
    92  func SendPrivacyTxCommand(cmd string) (string, bool) {
    93  
    94  	output, err := RunTuringchainCli(strings.Fields(cmd))
    95  
    96  	if err != nil {
    97  		return err.Error(), false
    98  	}
    99  
   100  	if strings.Contains(output, "Err") {
   101  		return output, false
   102  	}
   103  
   104  	var jsonMap map[string]interface{}
   105  	err = json.Unmarshal([]byte(output), &jsonMap)
   106  	if err != nil {
   107  		return output, false
   108  	}
   109  	output = jsonMap["hash"].(string)
   110  
   111  	return output, checkTxHashValid(output)
   112  }
   113  
   114  //GetTxRecpTyname get tx query -s TxHash
   115  func GetTxRecpTyname(txInfo map[string]interface{}) (tyname string, bSuccess bool) {
   116  
   117  	tyname = txInfo["receipt"].(map[string]interface{})["tyName"].(string)
   118  
   119  	bSuccess = false
   120  
   121  	if tyname == "ExecOk" {
   122  		bSuccess = true
   123  	}
   124  
   125  	return tyname, bSuccess
   126  }
   127  
   128  //GetTxInfo get tx receipt with tx hash code if exist
   129  func GetTxInfo(txHash string) (string, bool) {
   130  
   131  	bReady := false
   132  	txInfo, err := RunTuringchainCli(strings.Fields(fmt.Sprintf("tx query -s %s", txHash)))
   133  
   134  	if err == nil && txInfo != "tx not exist\n" {
   135  
   136  		bReady = true
   137  	} else if err != nil {
   138  
   139  		txInfo = err.Error()
   140  	}
   141  
   142  	return txInfo, bReady
   143  }
   144  
   145  //CheckBalanceDeltaWithAddr diff balance
   146  func CheckBalanceDeltaWithAddr(log map[string]interface{}, addr string, delta float64) bool {
   147  
   148  	logAddr := log["current"].(map[string]interface{})["addr"].(string)
   149  	prev, _ := strconv.ParseFloat(log["prev"].(map[string]interface{})["balance"].(string), 64)
   150  	curr, _ := strconv.ParseFloat(log["current"].(map[string]interface{})["balance"].(string), 64)
   151  
   152  	logDelta := (curr - prev) / 1e8
   153  
   154  	return (logAddr == addr) && (IsBalanceEqualFloat(logDelta, delta))
   155  }
   156  
   157  //CheckFrozenDeltaWithAddr check
   158  func CheckFrozenDeltaWithAddr(log map[string]interface{}, addr string, delta float64) bool {
   159  
   160  	logAddr := log["current"].(map[string]interface{})["addr"].(string)
   161  	prev, _ := strconv.ParseFloat(log["prev"].(map[string]interface{})["frozen"].(string), 64)
   162  	curr, _ := strconv.ParseFloat(log["current"].(map[string]interface{})["frozen"].(string), 64)
   163  
   164  	logDelta := (curr - prev) / 1e8
   165  
   166  	return (logAddr == addr) && (IsBalanceEqualFloat(logDelta, delta))
   167  }
   168  
   169  //CalcTxUtxoAmount calculate total amount in tx in/out utxo set, key = ["keyinput" | "keyoutput"]
   170  func CalcTxUtxoAmount(log map[string]interface{}, key string) float64 {
   171  
   172  	if log[key] == nil {
   173  		return 0
   174  	}
   175  
   176  	utxoArr := log[key].([]interface{})
   177  	var totalAmount float64
   178  
   179  	for i := range utxoArr {
   180  
   181  		temp, _ := strconv.ParseFloat(utxoArr[i].(map[string]interface{})["amount"].(string), 64)
   182  		totalAmount += temp
   183  	}
   184  
   185  	return totalAmount / 1e8
   186  }
   187  
   188  //CalcUtxoAvailAmount calculate available utxo with specific addr and TxHash
   189  func CalcUtxoAvailAmount(addr string, txHash string) (float64, error) {
   190  
   191  	outStr, err := RunTuringchainCli(strings.Fields(fmt.Sprintf("privacy showpai -d 1 -a %s", addr)))
   192  
   193  	if err != nil {
   194  		return 0, err
   195  	}
   196  	var jsonMap map[string]interface{}
   197  	err = json.Unmarshal([]byte(outStr), &jsonMap)
   198  
   199  	if err != nil {
   200  		return 0, err
   201  	}
   202  
   203  	var totalAmount float64
   204  	if jsonMap["AvailableDetail"] == nil {
   205  		return 0, nil
   206  	}
   207  
   208  	availArr := jsonMap["AvailableDetail"].([]interface{})
   209  
   210  	for i := range availArr {
   211  
   212  		if availArr[i].(map[string]interface{})["Txhash"].(string) == txHash {
   213  
   214  			temp, _ := strconv.ParseFloat(availArr[i].(map[string]interface{})["Amount"].(string), 64)
   215  			totalAmount += temp
   216  		}
   217  	}
   218  
   219  	return totalAmount, nil
   220  }
   221  
   222  //CalcUtxoSpendAmount calculate spend utxo with specific addr and TxHash
   223  func CalcUtxoSpendAmount(addr string, txHash string) (float64, error) {
   224  
   225  	outStr, err := RunTuringchainCli(strings.Fields(fmt.Sprintf("privacy showpas -a %s", addr)))
   226  
   227  	if strings.Contains(outStr, "Err") {
   228  		return 0, errors.New(outStr)
   229  	}
   230  
   231  	idx := strings.Index(outStr, "\n") + 1
   232  
   233  	if err != nil {
   234  		return 0, err
   235  	}
   236  	var jsonArr []interface{}
   237  	err = json.Unmarshal([]byte(outStr[idx:]), &jsonArr)
   238  
   239  	if err != nil {
   240  		return 0, err
   241  	}
   242  
   243  	var totalAmount float64
   244  
   245  	for i := range jsonArr {
   246  
   247  		if jsonArr[i].(map[string]interface{})["Txhash"].(string) == txHash[2:] {
   248  
   249  			spendArr := jsonArr[i].(map[string]interface{})["Spend"].([]interface{})
   250  			for i := range spendArr {
   251  
   252  				temp, _ := strconv.ParseFloat(spendArr[i].(map[string]interface{})["Amount"].(string), 64)
   253  				totalAmount += temp
   254  			}
   255  
   256  			break
   257  		}
   258  	}
   259  
   260  	return totalAmount, nil
   261  }