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 }