github.com/turingchain2020/turingchain@v1.1.21/types/types.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 实现了turingchain基础结构体、接口、常量等的定义
     6  package types
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/hex"
    11  	"encoding/json"
    12  	"fmt"
    13  	"strings"
    14  	"time"
    15  	"unsafe"
    16  
    17  	"github.com/turingchain2020/turingchain/common"
    18  	"github.com/turingchain2020/turingchain/common/address"
    19  	"github.com/turingchain2020/turingchain/common/crypto"
    20  	log "github.com/turingchain2020/turingchain/common/log/log15"
    21  	"github.com/turingchain2020/turingchain/types/jsonpb"
    22  	"github.com/golang/protobuf/proto"
    23  
    24  	// 注册system的crypto 加密算法
    25  	_ "github.com/turingchain2020/turingchain/system/crypto/init"
    26  )
    27  
    28  var tlog = log.New("module", "types")
    29  
    30  // Size1Kshiftlen tx消息大小1k
    31  const Size1Kshiftlen uint = 10
    32  
    33  // Message 声明proto.Message
    34  type Message proto.Message
    35  
    36  //ExecName  执行器name
    37  func (c *TuringchainConfig) ExecName(name string) string {
    38  	if len(name) > 1 && name[0] == '#' {
    39  		return name[1:]
    40  	}
    41  	if IsParaExecName(name) {
    42  		return name
    43  	}
    44  	if c.IsPara() {
    45  		return c.GetTitle() + name
    46  	}
    47  	return name
    48  }
    49  
    50  //IsAllowExecName 默认的allow 规则->根据 GetRealExecName 来判断
    51  //name 必须大于3 小于 100
    52  func IsAllowExecName(name []byte, execer []byte) bool {
    53  	// name长度不能超过系统限制
    54  	if len(name) > address.MaxExecNameLength || len(execer) > address.MaxExecNameLength {
    55  		return false
    56  	}
    57  	if len(name) < 3 || len(execer) < 3 {
    58  		return false
    59  	}
    60  	// name中不允许有 "-"
    61  	if bytes.Contains(name, slash) || bytes.Contains(name, sharp) {
    62  		return false
    63  	}
    64  	if !bytes.Equal(name, execer) && !bytes.Equal(name, GetRealExecName(execer)) {
    65  		return false
    66  	}
    67  	if bytes.HasPrefix(name, UserKey) {
    68  		return true
    69  	}
    70  	for i := range AllowUserExec {
    71  		if bytes.Equal(AllowUserExec[i], name) {
    72  			return true
    73  		}
    74  	}
    75  	return false
    76  }
    77  
    78  var bytesExec = []byte("exec-")
    79  var commonPrefix = []byte("mavl-")
    80  
    81  //GetExecKey  获取执行器key
    82  func GetExecKey(key []byte) (string, bool) {
    83  	n := 0
    84  	start := 0
    85  	end := 0
    86  	for i := len(commonPrefix); i < len(key); i++ {
    87  		if key[i] == '-' {
    88  			n = n + 1
    89  			if n == 2 {
    90  				start = i + 1
    91  			}
    92  			if n == 3 {
    93  				end = i
    94  				break
    95  			}
    96  		}
    97  	}
    98  	if start > 0 && end > 0 {
    99  		if bytes.Equal(key[start:end+1], bytesExec) {
   100  			//find addr
   101  			start = end + 1
   102  			for k := end; k < len(key); k++ {
   103  				if key[k] == ':' { //end+1
   104  					end = k
   105  					return string(key[start:end]), true
   106  				}
   107  			}
   108  		}
   109  	}
   110  	return "", false
   111  }
   112  
   113  //FindExecer  查找执行器
   114  func FindExecer(key []byte) (execer []byte, err error) {
   115  	if !bytes.HasPrefix(key, commonPrefix) {
   116  		return nil, ErrMavlKeyNotStartWithMavl
   117  	}
   118  	for i := len(commonPrefix); i < len(key); i++ {
   119  		if key[i] == '-' {
   120  			return key[len(commonPrefix):i], nil
   121  		}
   122  	}
   123  	return nil, ErrNoExecerInMavlKey
   124  }
   125  
   126  //GetParaExec  获取平行链执行
   127  func (c *TuringchainConfig) GetParaExec(execer []byte) []byte {
   128  	//必须是平行链
   129  	if !c.IsPara() {
   130  		return execer
   131  	}
   132  	//必须是相同的平行链
   133  	if !strings.HasPrefix(string(execer), c.GetTitle()) {
   134  		return execer
   135  	}
   136  	return execer[len(c.GetTitle()):]
   137  }
   138  
   139  //GetParaExecName 获取平行链上的执行器
   140  func GetParaExecName(execer []byte) []byte {
   141  	if !bytes.HasPrefix(execer, ParaKey) {
   142  		return execer
   143  	}
   144  	count := 0
   145  	for i := 0; i < len(execer); i++ {
   146  		if execer[i] == '.' {
   147  			count++
   148  		}
   149  		if count == 3 && i < (len(execer)-1) {
   150  			newexec := execer[i+1:]
   151  			return newexec
   152  		}
   153  	}
   154  	return execer
   155  }
   156  
   157  //GetRealExecName  获取真实的执行器name
   158  func GetRealExecName(execer []byte) []byte {
   159  	//平行链执行器,获取真实执行器的规则
   160  	execer = GetParaExecName(execer)
   161  	//平行链嵌套平行链是不被允许的
   162  	if bytes.HasPrefix(execer, ParaKey) {
   163  		return execer
   164  	}
   165  	if bytes.HasPrefix(execer, UserKey) {
   166  		//不是user.p. 的情况, 而是user. 的情况
   167  		count := 0
   168  		index := 0
   169  		for i := 0; i < len(execer); i++ {
   170  			if execer[i] == '.' {
   171  				count++
   172  			}
   173  			index = i
   174  			if count == 2 {
   175  				index--
   176  				break
   177  			}
   178  		}
   179  		e := execer[len(UserKey) : index+1]
   180  		if len(e) > 0 {
   181  			return e
   182  		}
   183  	}
   184  	return execer
   185  }
   186  
   187  //Encode  编码
   188  func Encode(data proto.Message) []byte {
   189  	b, err := proto.Marshal(data)
   190  	if err != nil {
   191  		panic(err)
   192  	}
   193  	return b
   194  }
   195  
   196  //Size  消息大小
   197  func Size(data proto.Message) int {
   198  	return proto.Size(data)
   199  }
   200  
   201  //Decode  解码
   202  func Decode(data []byte, msg proto.Message) error {
   203  	return proto.Unmarshal(data, msg)
   204  }
   205  
   206  //JSONToPB  JSON格式转换成protobuffer格式
   207  func JSONToPB(data []byte, msg proto.Message) error {
   208  	return jsonpb.Unmarshal(bytes.NewReader(data), msg)
   209  }
   210  
   211  //JSONToPBUTF8 默认解码utf8的字符串成bytes
   212  func JSONToPBUTF8(data []byte, msg proto.Message) error {
   213  	decode := &jsonpb.Unmarshaler{EnableUTF8BytesToString: true}
   214  	return decode.Unmarshal(bytes.NewReader(data), msg)
   215  }
   216  
   217  //Hash  计算叶子节点的hash
   218  func (leafnode *LeafNode) Hash() []byte {
   219  	data, err := proto.Marshal(leafnode)
   220  	if err != nil {
   221  		panic(err)
   222  	}
   223  	return common.Sha256(data)
   224  }
   225  
   226  var sha256Len = 32
   227  
   228  //Hash  计算中间节点的hash
   229  func (innernode *InnerNode) Hash() []byte {
   230  	rightHash := innernode.RightHash
   231  	leftHash := innernode.LeftHash
   232  	hashLen := sha256Len
   233  	if len(innernode.RightHash) > hashLen {
   234  		innernode.RightHash = innernode.RightHash[len(innernode.RightHash)-hashLen:]
   235  	}
   236  	if len(innernode.LeftHash) > hashLen {
   237  		innernode.LeftHash = innernode.LeftHash[len(innernode.LeftHash)-hashLen:]
   238  	}
   239  	data, err := proto.Marshal(innernode)
   240  	if err != nil {
   241  		panic(err)
   242  	}
   243  	innernode.RightHash = rightHash
   244  	innernode.LeftHash = leftHash
   245  	return common.Sha256(data)
   246  }
   247  
   248  //NewErrReceipt  new一个新的Receipt
   249  func NewErrReceipt(err error) *Receipt {
   250  	berr := err.Error()
   251  	errlog := &ReceiptLog{Ty: TyLogErr, Log: []byte(berr)}
   252  	return &Receipt{Ty: ExecErr, KV: nil, Logs: []*ReceiptLog{errlog}}
   253  }
   254  
   255  //CheckAmount  检测转账金额
   256  func CheckAmount(amount int64) bool {
   257  	if amount <= 0 || amount >= MaxCoin {
   258  		return false
   259  	}
   260  	return true
   261  }
   262  
   263  //GetEventName  获取时间name通过事件id
   264  func GetEventName(event int) string {
   265  	name, ok := eventName[event]
   266  	if ok {
   267  		return name
   268  	}
   269  	return "unknow-event"
   270  }
   271  
   272  //GetSignName  获取签名类型
   273  func GetSignName(execer string, signType int) string {
   274  	//优先加载执行器的签名类型
   275  	if execer != "" {
   276  		exec := LoadExecutorType(execer)
   277  		if exec != nil {
   278  			name, err := exec.GetCryptoDriver(signType)
   279  			if err == nil {
   280  				return name
   281  			}
   282  		}
   283  	}
   284  	//加载系统执行器的签名类型
   285  	return crypto.GetName(signType)
   286  }
   287  
   288  //GetSignType  获取签名类型
   289  func GetSignType(execer string, name string) int {
   290  	//优先加载执行器的签名类型
   291  	if execer != "" {
   292  		exec := LoadExecutorType(execer)
   293  		if exec != nil {
   294  			ty, err := exec.GetCryptoType(name)
   295  			if err == nil {
   296  				return ty
   297  			}
   298  		}
   299  	}
   300  	//加载系统执行器的签名类型
   301  	return crypto.GetType(name)
   302  }
   303  
   304  // ConfigPrefix 配置前缀key
   305  var ConfigPrefix = "mavl-config-"
   306  
   307  // ConfigKey 原来实现有bug, 但生成的key在状态树里, 不可修改
   308  // mavl-config–{key}  key 前面两个-
   309  func ConfigKey(key string) string {
   310  	return fmt.Sprintf("%s-%s", ConfigPrefix, key)
   311  }
   312  
   313  // ManagePrefix 超级管理员账户配置前缀key
   314  var ManagePrefix = "mavl-"
   315  
   316  //ManageKey 超级管理员账户key
   317  func ManageKey(key string) string {
   318  	return fmt.Sprintf("%s-%s", ManagePrefix+"manage", key)
   319  }
   320  
   321  //ManaeKeyWithHeigh 超级管理员账户key
   322  func (c *TuringchainConfig) ManaeKeyWithHeigh(key string, height int64) string {
   323  	if c.IsFork(height, "ForkExecKey") {
   324  		return ManageKey(key)
   325  	}
   326  	return ConfigKey(key)
   327  }
   328  
   329  //ReceiptDataResult 回执数据
   330  type ReceiptDataResult struct {
   331  	Ty     int32               `json:"ty"`
   332  	TyName string              `json:"tyname"`
   333  	Logs   []*ReceiptLogResult `json:"logs"`
   334  }
   335  
   336  //ReceiptLogResult 回执log数据
   337  type ReceiptLogResult struct {
   338  	Ty     int32       `json:"ty"`
   339  	TyName string      `json:"tyname"`
   340  	Log    interface{} `json:"log"`
   341  	RawLog string      `json:"rawlog"`
   342  }
   343  
   344  //DecodeReceiptLog 编码回执数据
   345  func (r *ReceiptData) DecodeReceiptLog(execer []byte) (*ReceiptDataResult, error) {
   346  	result := &ReceiptDataResult{Ty: r.GetTy()}
   347  	switch r.Ty {
   348  	case 0:
   349  		result.TyName = "ExecErr"
   350  	case 1:
   351  		result.TyName = "ExecPack"
   352  	case 2:
   353  		result.TyName = "ExecOk"
   354  	default:
   355  		return nil, ErrLogType
   356  	}
   357  
   358  	logs := r.GetLogs()
   359  	for _, l := range logs {
   360  		var lTy string
   361  		var logIns interface{}
   362  		lLog, err := hex.DecodeString(common.ToHex(l.GetLog())[2:])
   363  		if err != nil {
   364  			return nil, err
   365  		}
   366  
   367  		logType := LoadLog(execer, int64(l.Ty))
   368  		if logType == nil {
   369  			//tlog.Error("DecodeReceiptLog:", "Faile to decodeLog with type value logtype", l.Ty)
   370  			return nil, ErrLogType
   371  		}
   372  
   373  		logIns, _ = logType.Decode(lLog)
   374  		lTy = logType.Name()
   375  
   376  		result.Logs = append(result.Logs, &ReceiptLogResult{Ty: l.Ty, TyName: lTy, Log: logIns, RawLog: common.ToHex(l.GetLog())})
   377  	}
   378  	return result, nil
   379  }
   380  
   381  //OutputReceiptDetails 输出回执数据详情
   382  func (r *ReceiptData) OutputReceiptDetails(execer []byte, logger log.Logger) {
   383  	rds, err := r.DecodeReceiptLog(execer)
   384  	if err == nil {
   385  		logger.Debug("receipt decode", "receipt data", rds)
   386  		for _, rdl := range rds.Logs {
   387  			logger.Debug("receipt log", "log", rdl)
   388  		}
   389  	} else {
   390  		logger.Error("decodelogerr", "err", err)
   391  	}
   392  }
   393  
   394  //IterateRangeByStateHash 迭代查找
   395  func (t *ReplyGetTotalCoins) IterateRangeByStateHash(key, value []byte) bool {
   396  	tlog.Debug("ReplyGetTotalCoins.IterateRangeByStateHash", "key", string(key))
   397  	var acc Account
   398  	err := Decode(value, &acc)
   399  	if err != nil {
   400  		tlog.Error("ReplyGetTotalCoins.IterateRangeByStateHash", "err", err)
   401  		return true
   402  	}
   403  	//tlog.Info("acc:", "value", acc)
   404  	if t.Num >= t.Count {
   405  		t.NextKey = key
   406  		return true
   407  	}
   408  	t.Num++
   409  	t.Amount += acc.Balance
   410  	return false
   411  }
   412  
   413  // GetTxTimeInterval 获取交易有效期
   414  func GetTxTimeInterval() time.Duration {
   415  	return time.Second * 120
   416  }
   417  
   418  // ParaCrossTx 平行跨链交易
   419  type ParaCrossTx interface {
   420  	IsParaCrossTx() bool
   421  }
   422  
   423  // PBToJSON 消息类型转换
   424  func PBToJSON(r Message) ([]byte, error) {
   425  	encode := &jsonpb.Marshaler{EmitDefaults: true}
   426  	var buf bytes.Buffer
   427  	if err := encode.Marshal(&buf, r); err != nil {
   428  		return nil, err
   429  	}
   430  	return buf.Bytes(), nil
   431  }
   432  
   433  // PBToJSONUTF8 消息类型转换
   434  func PBToJSONUTF8(r Message) ([]byte, error) {
   435  	encode := &jsonpb.Marshaler{EmitDefaults: true, EnableUTF8BytesToString: true}
   436  	var buf bytes.Buffer
   437  	if err := encode.Marshal(&buf, r); err != nil {
   438  		return nil, err
   439  	}
   440  	return buf.Bytes(), nil
   441  }
   442  
   443  //MustPBToJSON panic when error
   444  func MustPBToJSON(req Message) []byte {
   445  	data, err := PBToJSON(req)
   446  	if err != nil {
   447  		panic(err)
   448  	}
   449  	return data
   450  }
   451  
   452  // MustDecode 数据是否已经编码
   453  func MustDecode(data []byte, v interface{}) {
   454  	if data == nil {
   455  		return
   456  	}
   457  	err := json.Unmarshal(data, v)
   458  	if err != nil {
   459  		panic(err)
   460  	}
   461  }
   462  
   463  // AddItem 添加item
   464  func (t *ReplyGetExecBalance) AddItem(execAddr, value []byte) {
   465  	var acc Account
   466  	err := Decode(value, &acc)
   467  	if err != nil {
   468  		tlog.Error("ReplyGetExecBalance.AddItem", "err", err)
   469  		return
   470  	}
   471  	tlog.Info("acc:", "value", acc)
   472  	t.Amount += acc.Balance
   473  	t.Amount += acc.Frozen
   474  
   475  	t.AmountActive += acc.Balance
   476  	t.AmountFrozen += acc.Frozen
   477  
   478  	item := &ExecBalanceItem{ExecAddr: execAddr, Frozen: acc.Frozen, Active: acc.Balance}
   479  	t.Items = append(t.Items, item)
   480  }
   481  
   482  //Clone  克隆
   483  func Clone(data proto.Message) proto.Message {
   484  	return proto.Clone(data)
   485  }
   486  
   487  //Clone 添加一个浅拷贝函数
   488  func (sig *Signature) Clone() *Signature {
   489  	if sig == nil {
   490  		return nil
   491  	}
   492  	return &Signature{
   493  		Ty:        sig.Ty,
   494  		Pubkey:    sig.Pubkey,
   495  		Signature: sig.Signature,
   496  	}
   497  }
   498  
   499  //Clone 浅拷贝: BlockDetail
   500  func (b *BlockDetail) Clone() *BlockDetail {
   501  	if b == nil {
   502  		return nil
   503  	}
   504  	return &BlockDetail{
   505  		Block:          b.Block.Clone(),
   506  		Receipts:       cloneReceipts(b.Receipts),
   507  		KV:             cloneKVList(b.KV),
   508  		PrevStatusHash: b.PrevStatusHash,
   509  	}
   510  }
   511  
   512  //Clone 浅拷贝ReceiptData
   513  func (r *ReceiptData) Clone() *ReceiptData {
   514  	if r == nil {
   515  		return nil
   516  	}
   517  	return &ReceiptData{
   518  		Ty:   r.Ty,
   519  		Logs: cloneReceiptLogs(r.Logs),
   520  	}
   521  }
   522  
   523  //Clone 浅拷贝 receiptLog
   524  func (r *ReceiptLog) Clone() *ReceiptLog {
   525  	if r == nil {
   526  		return nil
   527  	}
   528  	return &ReceiptLog{
   529  		Ty:  r.Ty,
   530  		Log: r.Log,
   531  	}
   532  }
   533  
   534  //Clone KeyValue
   535  func (kv *KeyValue) Clone() *KeyValue {
   536  	if kv == nil {
   537  		return nil
   538  	}
   539  	return &KeyValue{
   540  		Key:   kv.Key,
   541  		Value: kv.Value,
   542  	}
   543  }
   544  
   545  //Clone Block 浅拷贝(所有的types.Message 进行了拷贝)
   546  func (b *Block) Clone() *Block {
   547  	if b == nil {
   548  		return nil
   549  	}
   550  	return &Block{
   551  		Version:    b.Version,
   552  		ParentHash: b.ParentHash,
   553  		TxHash:     b.TxHash,
   554  		StateHash:  b.StateHash,
   555  		Height:     b.Height,
   556  		BlockTime:  b.BlockTime,
   557  		Difficulty: b.Difficulty,
   558  		MainHash:   b.MainHash,
   559  		MainHeight: b.MainHeight,
   560  		Signature:  b.Signature.Clone(),
   561  		Txs:        cloneTxs(b.Txs),
   562  	}
   563  }
   564  
   565  //Clone BlockBody 浅拷贝(所有的types.Message 进行了拷贝)
   566  func (b *BlockBody) Clone() *BlockBody {
   567  	if b == nil {
   568  		return nil
   569  	}
   570  	return &BlockBody{
   571  		Txs:        cloneTxs(b.Txs),
   572  		Receipts:   cloneReceipts(b.Receipts),
   573  		MainHash:   b.MainHash,
   574  		MainHeight: b.MainHeight,
   575  		Hash:       b.Hash,
   576  		Height:     b.Height,
   577  	}
   578  }
   579  
   580  //cloneReceipts 浅拷贝交易回报
   581  func cloneReceipts(b []*ReceiptData) []*ReceiptData {
   582  	if b == nil {
   583  		return nil
   584  	}
   585  	rs := make([]*ReceiptData, len(b))
   586  	for i := 0; i < len(b); i++ {
   587  		rs[i] = b[i].Clone()
   588  	}
   589  	return rs
   590  }
   591  
   592  //cloneReceiptLogs 浅拷贝 ReceiptLogs
   593  func cloneReceiptLogs(b []*ReceiptLog) []*ReceiptLog {
   594  	if b == nil {
   595  		return nil
   596  	}
   597  	rs := make([]*ReceiptLog, len(b))
   598  	for i := 0; i < len(b); i++ {
   599  		rs[i] = b[i].Clone()
   600  	}
   601  	return rs
   602  }
   603  
   604  //cloneKVList 拷贝kv 列表
   605  func cloneKVList(b []*KeyValue) []*KeyValue {
   606  	if b == nil {
   607  		return nil
   608  	}
   609  	kv := make([]*KeyValue, len(b))
   610  	for i := 0; i < len(b); i++ {
   611  		kv[i] = b[i].Clone()
   612  	}
   613  	return kv
   614  }
   615  
   616  // Bytes2Str 高效字节数组转字符串
   617  // 相比普通直接转化,性能提升35倍,提升程度和转换的byte长度线性相关,且不存在内存开销
   618  // 需要注意b的修改会导致最终string的变更,比较适合临时变量转换,不适合
   619  func Bytes2Str(b []byte) string {
   620  	return *(*string)(unsafe.Pointer(&b))
   621  }
   622  
   623  // Str2Bytes 高效字符串转字节数组
   624  // 相比普通直接转化,性能提升13倍, 提升程度和转换的byte长度线性相关,且不存在内存开销
   625  // 需要注意不能修改转换后的byte数组,本质上是修改了底层string,将会panic
   626  func Str2Bytes(s string) []byte {
   627  	x := (*[2]uintptr)(unsafe.Pointer(&s))
   628  	h := [3]uintptr{x[0], x[1], x[1]}
   629  	return *(*[]byte)(unsafe.Pointer(&h))
   630  }
   631  
   632  //Hash  计算hash
   633  func (hashes *ReplyHashes) Hash() []byte {
   634  	data, err := proto.Marshal(hashes)
   635  	if err != nil {
   636  		panic(err)
   637  	}
   638  	return common.Sha256(data)
   639  }