github.com/turingchain2020/turingchain@v1.1.21/types/types_test.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 "bytes" 9 "encoding/gob" 10 "encoding/hex" 11 "encoding/json" 12 "fmt" 13 "reflect" 14 "testing" 15 16 "github.com/turingchain2020/turingchain/common" 17 "github.com/turingchain2020/turingchain/types/jsonpb" 18 proto "github.com/golang/protobuf/proto" 19 "github.com/stretchr/testify/assert" 20 ) 21 22 func TestAllowExecName(t *testing.T) { 23 //allow exec list 24 old := AllowUserExec 25 defer func() { 26 AllowUserExec = old 27 }() 28 AllowUserExec = nil 29 AllowUserExec = append(AllowUserExec, []byte("coins")) 30 isok := IsAllowExecName([]byte("a"), []byte("a")) 31 assert.Equal(t, isok, false) 32 33 isok = IsAllowExecName([]byte("coins"), []byte("coins")) 34 assert.Equal(t, isok, true) 35 36 isok = IsAllowExecName([]byte("coins"), []byte("user.coins")) 37 assert.Equal(t, isok, true) 38 39 isok = IsAllowExecName([]byte("coins"), []byte("user.coinsx")) 40 assert.Equal(t, isok, false) 41 42 isok = IsAllowExecName([]byte("coins"), []byte("user.coins.evm2")) 43 assert.Equal(t, isok, true) 44 45 isok = IsAllowExecName([]byte("coins"), []byte("user.p.guodun.coins.evm2")) 46 assert.Equal(t, isok, false) 47 48 isok = IsAllowExecName([]byte("coins"), []byte("user.p.guodun.coins")) 49 assert.Equal(t, isok, true) 50 51 isok = IsAllowExecName([]byte("coins"), []byte("user.p.guodun.user.coins")) 52 assert.Equal(t, isok, true) 53 54 isok = IsAllowExecName([]byte("#coins"), []byte("user.p.guodun.user.coins")) 55 assert.Equal(t, isok, false) 56 57 isok = IsAllowExecName([]byte("coins-"), []byte("user.p.guodun.user.coins")) 58 assert.Equal(t, isok, false) 59 } 60 61 func BenchmarkExecName(b *testing.B) { 62 cfg := NewTuringchainConfig(GetDefaultCfgstring()) 63 for i := 0; i < b.N; i++ { 64 cfg.ExecName("hello") 65 } 66 } 67 68 func BenchmarkG(b *testing.B) { 69 cfg := NewTuringchainConfig(GetDefaultCfgstring()) 70 for i := 0; i < b.N; i++ { 71 cfg.G("TestNet") 72 } 73 } 74 75 func BenchmarkS(b *testing.B) { 76 cfg := NewTuringchainConfig(GetDefaultCfgstring()) 77 for i := 0; i < b.N; i++ { 78 cfg.S("helloword", true) 79 } 80 } 81 func TestJsonNoName(t *testing.T) { 82 flag := int32(1) 83 params := struct { 84 Flag int32 85 }{ 86 Flag: flag, 87 } 88 data, err := json.Marshal(params) 89 if err != nil { 90 t.Error(err) 91 } 92 assert.Equal(t, string(data), "{\"Flag\":1}") 93 } 94 95 func TestNil(t *testing.T) { 96 v := reflect.ValueOf(nil) 97 assert.Equal(t, v.IsValid(), false) 98 } 99 100 func TestProtoToJson(t *testing.T) { 101 r := &Reply{} 102 b, err := json.Marshal(r) 103 assert.Nil(t, err) 104 assert.Equal(t, b, []byte(`{}`)) 105 106 encode := &jsonpb.Marshaler{EmitDefaults: true} 107 s, err := encode.MarshalToString(r) 108 assert.Nil(t, err) 109 assert.Equal(t, s, `{"isOk":false,"msg":null}`) 110 var dr Reply 111 err = jsonpb.UnmarshalString(`{"isOk":false,"msg":null}`, &dr) 112 assert.Nil(t, err) 113 assert.Nil(t, dr.Msg) 114 encode2 := &jsonpb.Marshaler{EmitDefaults: false} 115 s, err = encode2.MarshalToString(r) 116 assert.Nil(t, err) 117 assert.Equal(t, s, `{}`) 118 119 r = &Reply{Msg: []byte("OK")} 120 b, err = json.Marshal(r) 121 assert.Nil(t, err) 122 assert.Equal(t, b, []byte(`{"msg":"T0s="}`)) 123 124 encode = &jsonpb.Marshaler{EmitDefaults: true} 125 s, err = encode.MarshalToString(r) 126 assert.Nil(t, err) 127 assert.Equal(t, s, `{"isOk":false,"msg":"0x4f4b"}`) 128 129 err = jsonpb.UnmarshalString(`{"isOk":false,"msg":"0x4f4b"}`, &dr) 130 assert.Nil(t, err) 131 assert.Equal(t, dr.Msg, []byte("OK")) 132 133 err = jsonpb.UnmarshalString(`{"isOk":false,"msg":"4f4b"}`, &dr) 134 assert.Equal(t, err, jsonpb.ErrBytesFormat) 135 136 err = jsonpb.UnmarshalString(`{"isOk":false,"msg":"0x"}`, &dr) 137 assert.Nil(t, err) 138 assert.Equal(t, dr.Msg, []byte("")) 139 140 err = jsonpb.UnmarshalString(`{"isOk":false,"msg":"str://OK"}`, &dr) 141 assert.Nil(t, err) 142 assert.Equal(t, dr.Msg, []byte("OK")) 143 144 err = jsonpb.UnmarshalString(`{"isOk":false,"msg":"str://0"}`, &dr) 145 assert.Nil(t, err) 146 assert.Equal(t, dr.Msg, []byte("0")) 147 148 r = &Reply{Msg: []byte{}} 149 b, err = json.Marshal(r) 150 assert.Nil(t, err) 151 assert.Equal(t, b, []byte(`{}`)) 152 153 encode = &jsonpb.Marshaler{EmitDefaults: true} 154 s, err = encode.MarshalToString(r) 155 assert.Nil(t, err) 156 assert.Equal(t, s, `{"isOk":false,"msg":""}`) 157 158 err = jsonpb.UnmarshalString(`{"isOk":false,"msg":""}`, &dr) 159 assert.Nil(t, err) 160 assert.Equal(t, dr.Msg, []byte{}) 161 } 162 163 func TestJsonpbUTF8(t *testing.T) { 164 r := &Reply{Msg: []byte("OK")} 165 b, err := PBToJSONUTF8(r) 166 assert.Nil(t, err) 167 assert.Equal(t, b, []byte(`{"isOk":false,"msg":"OK"}`)) 168 169 var newreply Reply 170 err = JSONToPBUTF8(b, &newreply) 171 assert.Nil(t, err) 172 assert.Equal(t, r, &newreply) 173 } 174 175 func TestJsonpb(t *testing.T) { 176 r := &Reply{Msg: []byte("OK")} 177 b, err := PBToJSON(r) 178 assert.Nil(t, err) 179 assert.Equal(t, b, []byte(`{"isOk":false,"msg":"0x4f4b"}`)) 180 181 var newreply Reply 182 err = JSONToPB(b, &newreply) 183 assert.Nil(t, err) 184 assert.Equal(t, r, &newreply) 185 } 186 187 func TestHex(t *testing.T) { 188 s := "0x4f4b" 189 b, err := common.FromHex(s) 190 assert.Nil(t, err) 191 assert.Equal(t, b, []byte("OK")) 192 } 193 194 func TestGetLogName(t *testing.T) { 195 name := GetLogName([]byte("xxx"), 0) 196 assert.Equal(t, "LogReserved", name) 197 assert.Equal(t, "LogErr", GetLogName([]byte("coins"), 1)) 198 assert.Equal(t, "LogFee", GetLogName([]byte("token"), 2)) 199 assert.Equal(t, "LogReserved", GetLogName([]byte("xxxx"), 100)) 200 } 201 202 func TestDecodeLog(t *testing.T) { 203 data, _ := common.FromHex("0x0a2b10c0c599b78c1d2222314c6d7952616a4e44686f735042746259586d694c466b5174623833673948795565122b1080ab8db78c1d2222314c6d7952616a4e44686f735042746259586d694c466b5174623833673948795565") 204 l, err := DecodeLog([]byte("xxx"), 2, data) 205 assert.Nil(t, err) 206 j, err := json.Marshal(l) 207 assert.Nil(t, err) 208 assert.Equal(t, "{\"prev\":{\"balance\":999769400000,\"addr\":\"1LmyRajNDhosPBtbYXmiLFkQtb83g9HyUe\"},\"current\":{\"balance\":999769200000,\"addr\":\"1LmyRajNDhosPBtbYXmiLFkQtb83g9HyUe\"}}", string(j)) 209 } 210 211 func TestGetRealExecName(t *testing.T) { 212 a := []struct { 213 key string 214 realkey string 215 }{ 216 {"coins", "coins"}, 217 {"user.p.coins", "user.p.coins"}, 218 {"user.p.guodun.coins", "coins"}, 219 {"user.evm.hash", "evm"}, 220 {"user.p.para.evm.hash", "evm.hash"}, 221 {"user.p.para.user.evm.hash", "evm"}, 222 {"user.p.para.", "user.p.para."}, 223 } 224 for _, v := range a { 225 assert.Equal(t, string(GetRealExecName([]byte(v.key))), v.realkey) 226 } 227 } 228 229 func genPrefixEdge(prefix []byte) (r []byte) { 230 for j := 0; j < len(prefix); j++ { 231 r = append(r, prefix[j]) 232 } 233 234 i := len(prefix) - 1 235 for i >= 0 { 236 if r[i] < 0xff { 237 r[i]++ 238 break 239 } else { 240 i-- 241 } 242 } 243 244 return r 245 } 246 247 func (t *StoreListReply) IterateCallBack(key, value []byte) bool { 248 if t.Mode == 1 { //[start, end) 249 if t.Num >= t.Count { 250 t.NextKey = key 251 return true 252 } 253 t.Num++ 254 t.Keys = append(t.Keys, cloneByte(key)) 255 t.Values = append(t.Values, cloneByte(value)) 256 return false 257 } else if t.Mode == 2 { //prefix + suffix 258 if len(key) > len(t.Suffix) { 259 if string(key[len(key)-len(t.Suffix):]) == string(t.Suffix) { 260 t.Num++ 261 t.Keys = append(t.Keys, cloneByte(key)) 262 t.Values = append(t.Values, cloneByte(value)) 263 if t.Num >= t.Count { 264 t.NextKey = key 265 return true 266 } 267 } 268 return false 269 } 270 return false 271 } else { 272 fmt.Println("StoreListReply.IterateCallBack unsupported mode", "mode", t.Mode) 273 return true 274 } 275 } 276 277 func cloneByte(v []byte) []byte { 278 value := make([]byte, len(v)) 279 copy(value, v) 280 return value 281 } 282 283 func TestIterateCallBack_PrefixWithoutExecAddr(t *testing.T) { 284 key := "mavl-coins-trc-exec-16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP" 285 //prefix1 := "mavl-coins-trc-exec-16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:" 286 prefix2 := "mavl-coins-trc-exec-" 287 //execAddr := "16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp" 288 addr := "1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP" 289 290 var reply = &StoreListReply{ 291 Start: []byte(prefix2), 292 End: genPrefixEdge([]byte(prefix2)), 293 Suffix: []byte(addr), 294 Mode: int64(2), 295 Count: int64(100), 296 } 297 298 var acc = &Account{ 299 Currency: 0, 300 Balance: 1, 301 Frozen: 1, 302 Addr: addr, 303 } 304 305 value := Encode(acc) 306 307 bRet := reply.IterateCallBack([]byte(key), value) 308 assert.Equal(t, false, bRet) 309 assert.Equal(t, 1, len(reply.Keys)) 310 assert.Equal(t, 1, len(reply.Values)) 311 assert.Equal(t, int64(1), reply.Num) 312 assert.Equal(t, 0, len(reply.NextKey)) 313 314 bRet = reply.IterateCallBack([]byte(key), value) 315 assert.Equal(t, false, bRet) 316 assert.Equal(t, 2, len(reply.Keys)) 317 assert.Equal(t, 2, len(reply.Values)) 318 assert.Equal(t, int64(2), reply.Num) 319 assert.Equal(t, 0, len(reply.NextKey)) 320 321 key2 := "mavl-coins-trc-exec-16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:2JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP" 322 bRet = reply.IterateCallBack([]byte(key2), value) 323 assert.Equal(t, false, bRet) 324 assert.Equal(t, 2, len(reply.Keys)) 325 assert.Equal(t, 2, len(reply.Values)) 326 assert.Equal(t, int64(2), reply.Num) 327 assert.Equal(t, 0, len(reply.NextKey)) 328 329 key3 := "mavl-coins-trc-exec-26htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP" 330 bRet = reply.IterateCallBack([]byte(key3), value) 331 assert.Equal(t, false, bRet) 332 assert.Equal(t, 3, len(reply.Keys)) 333 assert.Equal(t, 3, len(reply.Values)) 334 assert.Equal(t, int64(3), reply.Num) 335 assert.Equal(t, 0, len(reply.NextKey)) 336 337 reply.Count = int64(4) 338 339 bRet = reply.IterateCallBack([]byte(key3), value) 340 assert.Equal(t, true, bRet) 341 assert.Equal(t, 4, len(reply.Keys)) 342 assert.Equal(t, 4, len(reply.Values)) 343 assert.Equal(t, int64(4), reply.Num) 344 assert.Equal(t, key3, string(reply.NextKey)) 345 fmt.Println(string(reply.NextKey)) 346 } 347 348 func TestIterateCallBack_PrefixWithExecAddr(t *testing.T) { 349 key := "mavl-coins-trc-exec-16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP" 350 prefix1 := "mavl-coins-trc-exec-16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:" 351 //execAddr := "16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp" 352 addr := "1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP" 353 354 var reply = &StoreListReply{ 355 Start: []byte(prefix1), 356 End: genPrefixEdge([]byte(prefix1)), 357 Suffix: []byte(addr), 358 Mode: int64(2), 359 Count: int64(1), 360 } 361 362 var acc = &Account{ 363 Currency: 0, 364 Balance: 1, 365 Frozen: 1, 366 Addr: addr, 367 } 368 369 value := Encode(acc) 370 371 key2 := "mavl-coins-trc-exec-16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:2JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP" 372 bRet := reply.IterateCallBack([]byte(key2), value) 373 assert.Equal(t, false, bRet) 374 assert.Equal(t, 0, len(reply.Keys)) 375 assert.Equal(t, 0, len(reply.Values)) 376 assert.Equal(t, int64(0), reply.Num) 377 assert.Equal(t, 0, len(reply.NextKey)) 378 379 bRet = reply.IterateCallBack([]byte(key), value) 380 assert.Equal(t, true, bRet) 381 assert.Equal(t, 1, len(reply.Keys)) 382 assert.Equal(t, 1, len(reply.Values)) 383 assert.Equal(t, int64(1), reply.Num) 384 assert.Equal(t, len(key), len(reply.NextKey)) 385 386 //key2 := "mavl-coins-trc-exec-16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:2JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP" 387 reply.NextKey = nil 388 reply.Count = int64(2) 389 bRet = reply.IterateCallBack([]byte(key2), value) 390 assert.Equal(t, false, bRet) 391 assert.Equal(t, 1, len(reply.Keys)) 392 assert.Equal(t, 1, len(reply.Values)) 393 assert.Equal(t, int64(1), reply.Num) 394 assert.Equal(t, 0, len(reply.NextKey)) 395 396 reply.NextKey = nil 397 key3 := "mavl-coins-trc-exec-26htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp:1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP" 398 bRet = reply.IterateCallBack([]byte(key3), value) 399 assert.Equal(t, true, bRet) 400 assert.Equal(t, 2, len(reply.Keys)) 401 assert.Equal(t, 2, len(reply.Values)) 402 assert.Equal(t, int64(2), reply.Num) 403 assert.Equal(t, len(key3), len(reply.NextKey)) 404 405 bRet = reply.IterateCallBack([]byte(key), value) 406 assert.Equal(t, true, bRet) 407 assert.Equal(t, 3, len(reply.Keys)) 408 assert.Equal(t, 3, len(reply.Values)) 409 assert.Equal(t, int64(3), reply.Num) 410 assert.Equal(t, len(key), len(reply.NextKey)) 411 } 412 413 func TestJsonpbUTF8Tx(t *testing.T) { 414 NewTuringchainConfig(GetDefaultCfgstring()) 415 bdata, err := common.FromHex("0a05636f696e73121018010a0c108084af5f1a05310a320a3320e8b31b30b9b69483d7f9d3f04c3a22314b67453376617969715a4b6866684d66744e3776743267447639486f4d6b393431") 416 assert.Nil(t, err) 417 var r Transaction 418 err = Decode(bdata, &r) 419 assert.Nil(t, err) 420 plType := LoadExecutorType("coins") 421 var pl Message 422 if plType != nil { 423 pl, err = plType.DecodePayload(&r) 424 if err != nil { 425 pl = nil 426 } 427 } 428 var pljson json.RawMessage 429 assert.NotNil(t, pl) 430 pljson, err = PBToJSONUTF8(pl) 431 assert.Nil(t, err) 432 assert.Equal(t, string(pljson), `{"transfer":{"cointoken":"","amount":"200000000","note":"1\n2\n3","to":""},"ty":1}`) 433 } 434 435 func TestSignatureClone(t *testing.T) { 436 s1 := &Signature{Ty: 1, Pubkey: []byte("Pubkey1"), Signature: []byte("Signature1")} 437 s2 := s1.Clone() 438 s2.Pubkey = []byte("Pubkey2") 439 assert.Equal(t, s1.Ty, s2.Ty) 440 assert.Equal(t, s1.Signature, s2.Signature) 441 assert.Equal(t, []byte("Pubkey1"), s1.Pubkey) 442 assert.Equal(t, []byte("Pubkey2"), s2.Pubkey) 443 } 444 445 func TestTxClone(t *testing.T) { 446 s1 := &Signature{Ty: 1, Pubkey: []byte("Pubkey1"), Signature: []byte("Signature1")} 447 tx1 := &Transaction{Execer: []byte("Execer1"), Fee: 1, Signature: s1} 448 tx2 := tx1.Clone() 449 tx2.Signature.Pubkey = []byte("Pubkey2") 450 tx2.Fee = 2 451 assert.Equal(t, tx1.Execer, tx2.Execer) 452 assert.Equal(t, int64(1), tx1.Fee) 453 assert.Equal(t, tx1.Signature.Ty, tx2.Signature.Ty) 454 assert.Equal(t, []byte("Pubkey1"), tx1.Signature.Pubkey) 455 assert.Equal(t, []byte("Pubkey2"), tx2.Signature.Pubkey) 456 457 tx2.Signature = nil 458 assert.NotNil(t, tx1.Signature) 459 assert.Nil(t, tx2.Signature) 460 } 461 462 func TestBlockClone(t *testing.T) { 463 b1 := getTestBlockDetail() 464 b2 := b1.Clone() 465 466 b2.Block.Signature.Ty = 22 467 assert.NotEqual(t, b1.Block.Signature.Ty, b2.Block.Signature.Ty) 468 assert.Equal(t, b1.Block.Signature.Signature, b2.Block.Signature.Signature) 469 470 b2.Block.Txs[1].Execer = []byte("E22") 471 assert.NotEqual(t, b1.Block.Txs[1].Execer, b2.Block.Txs[1].Execer) 472 assert.Equal(t, b1.Block.Txs[1].Fee, b2.Block.Txs[1].Fee) 473 474 b2.KV[1].Key = []byte("key22") 475 assert.NotEqual(t, b1.KV[1].Key, b2.KV[1].Key) 476 assert.Equal(t, b1.KV[1].Value, b2.KV[1].Value) 477 478 b2.Receipts[1].Ty = 22 479 assert.NotEqual(t, b1.Receipts[1].Ty, b2.Receipts[1].Ty) 480 assert.Equal(t, b1.Receipts[1].Logs, b2.Receipts[1].Logs) 481 482 b2.Block.Txs[0] = nil 483 assert.NotNil(t, b1.Block.Txs[0]) 484 } 485 486 func TestBlockBody(t *testing.T) { 487 detail := getTestBlockDetail() 488 b1 := BlockBody{ 489 Txs: detail.Block.Txs, 490 Receipts: detail.Receipts, 491 MainHash: []byte("MainHash1"), 492 MainHeight: 1, 493 Hash: []byte("Hash"), 494 Height: 1, 495 } 496 b2 := b1.Clone() 497 498 b2.Txs[1].Execer = []byte("E22") 499 assert.NotEqual(t, b1.Txs[1].Execer, b2.Txs[1].Execer) 500 assert.Equal(t, b1.Txs[1].Fee, b2.Txs[1].Fee) 501 502 b2.Receipts[1].Ty = 22 503 assert.NotEqual(t, b1.Receipts[1].Ty, b2.Receipts[1].Ty) 504 assert.Equal(t, b1.Receipts[1].Logs, b2.Receipts[1].Logs) 505 506 b2.Txs[0] = nil 507 assert.NotNil(t, b1.Txs[0]) 508 509 b2.MainHash = []byte("MainHash2") 510 assert.NotEqual(t, b1.MainHash, b2.MainHash) 511 assert.Equal(t, b1.Height, b2.Height) 512 } 513 514 func getTestBlockDetail() *BlockDetail { 515 s1 := &Signature{Ty: 1, Pubkey: []byte("Pubkey1"), Signature: []byte("Signature1")} 516 s2 := &Signature{Ty: 2, Pubkey: []byte("Pubkey2"), Signature: []byte("Signature2")} 517 tx1 := &Transaction{Execer: []byte("Execer1"), Fee: 1, Signature: s1} 518 tx2 := &Transaction{Execer: []byte("Execer2"), Fee: 2, Signature: s2} 519 520 sigBlock := &Signature{Ty: 1, Pubkey: []byte("BlockPubkey1"), Signature: []byte("BlockSignature1")} 521 block := &Block{ 522 Version: 1, 523 ParentHash: []byte("ParentHash"), 524 TxHash: []byte("TxHash"), 525 StateHash: []byte("TxHash"), 526 Height: 1, 527 BlockTime: 1, 528 Difficulty: 1, 529 MainHash: []byte("MainHash"), 530 MainHeight: 1, 531 Signature: sigBlock, 532 Txs: []*Transaction{tx1, tx2}, 533 } 534 kv1 := &KeyValue{Key: []byte("key1"), Value: []byte("value1")} 535 kv2 := &KeyValue{Key: []byte("key1"), Value: []byte("value1")} 536 537 log1 := &ReceiptLog{Ty: 1, Log: []byte("log1")} 538 log2 := &ReceiptLog{Ty: 2, Log: []byte("log2")} 539 receipts := []*ReceiptData{ 540 {Ty: 11, Logs: []*ReceiptLog{log1}}, 541 {Ty: 12, Logs: []*ReceiptLog{log2}}, 542 } 543 544 return &BlockDetail{ 545 Block: block, 546 Receipts: receipts, 547 KV: []*KeyValue{kv1, kv2}, 548 PrevStatusHash: []byte("PrevStatusHash"), 549 } 550 } 551 552 // 测试数据对象复制效率 553 func deepCopy(dst, src interface{}) error { 554 var buf bytes.Buffer 555 if err := gob.NewEncoder(&buf).Encode(src); err != nil { 556 return err 557 } 558 return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst) 559 } 560 561 func BenchmarkDeepCody(b *testing.B) { 562 block := getRealBlockDetail() 563 if block == nil { 564 return 565 } 566 567 b.ResetTimer() 568 for i := 0; i < b.N; i++ { 569 var b1 *BlockDetail 570 _ = deepCopy(b1, block) 571 } 572 573 } 574 575 func BenchmarkProtoClone(b *testing.B) { 576 block := getRealBlockDetail() 577 if block == nil { 578 return 579 } 580 581 b.ResetTimer() 582 for i := 0; i < b.N; i++ { 583 _ = proto.Clone(block).(*BlockDetail) 584 } 585 } 586 587 func BenchmarkProtoMarshal(b *testing.B) { 588 block := getRealBlockDetail() 589 if block == nil { 590 return 591 } 592 593 b.ResetTimer() 594 for i := 0; i < b.N; i++ { 595 x, _ := proto.Marshal(block) 596 var b BlockDetail 597 proto.Unmarshal(x, &b) 598 } 599 } 600 601 func BenchmarkCopyBlockDetail(b *testing.B) { 602 block := getRealBlockDetail() 603 if block == nil { 604 return 605 } 606 607 b.ResetTimer() 608 for i := 0; i < b.N; i++ { 609 _ = block.Clone() 610 } 611 } 612 613 func getRealBlockDetail() *BlockDetail { 614 hexBlock := "0aad071220d29ccba4a90178614c8036f962201fdf56e77b419ca570371778e129a0e0e2841a20dd690056e7719d5b5fd1ad3e76f3b4366db9f3278ca29fbe4fc523bbf756fa8a222064cdbc89fe14ae7b851a71e41bd36a82db8cd3b69f4434f6420b279fea4fd25028e90330d386c4ea053a99040a067469636b657412ed02501022e80208ffff8bf8011080cab5ee011a70313271796f6361794e46374c7636433971573461767873324537553431664b5366763a3078386434663130653666313762616533636538663764303239616263623461393839616563333333386238386662333537656165663035613265326465373930343a30303030303035363533224230783537656632356366363036613734393462626164326432666233373734316137636332346663663066653064303637363638636564306235653961363735336632206b9836b2d295ca16634ea83359342db3ab1ab5f15200993bf6a09024089b7b693a810136f5a704a427a0562653345659193a0e292f16200ce67d6a8f8af631149a904fb80f0c12f525f7ce208fbf2183f2052af6252a108bb2614db0ccf8d91d4e910a04c472f5113275fe937f68ed6b2b0b522cc5fc2594b9fec60c0b22524b828333aaa982be125ec0f69645c86de3d331b26aa84c29a06824e977ce51f76f34f0629c1a6d080112210320bbac09528e19c55b0f89cb37ab265e7e856b1a8c388780322dbbfd194b52ba1a46304402200971163de32cb6a17e925eb3fcec8a0ccc193493635ecbf52357f5365edc2c82022039d84aa7078bc51ef83536038b7fd83087bf4deb965370f211a5589d4add551720a08d063097c5abcc9db1e4a92b3a22313668747663424e53454137665a6841644c4a706844775152514a614870794854703af4010a05746f6b656e124438070a400a0879696e6865626962120541424344452080d0dbc3f4022864322231513868474c666f47653633656665576138664a34506e756b686b6e677436706f4b38011a6d08011221021afd97c3d9a47f7ead3ca34fe5a73789714318df2c608cf2c7962378dc858ecb1a4630440220316a241f19b392e685ef940dee48dc53f90fc5c8be108ceeef1d3c65f530ee5f02204c89708cc7dac408a88e9fa6ad8e723d93fc18fe114d4a416e280f5a15656b0920a08d0628ca87c4ea0530dd91be81ae9ed1882d3a22313268704a4248796268316d537943696a51324d514a506b377a376b5a376a6e516158ffff8bf80162200b97166ad507aea57a4bb6e6b9295ec082cdc670b8468a83b559dbd900ffb83068e90312e80508021a5e0802125a0a2b1080978dcaef192222313271796f6361794e46374c7636433971573461767873324537553431664b536676122b10e08987caef192222313271796f6361794e46374c7636433971573461767873324537553431664b5366761a9f010871129a010a70313271796f6361794e46374c7636433971573461767873324537553431664b5366763a3078386434663130653666313762616533636538663764303239616263623461393839616563333333386238386662333537656165663035613265326465373930343a30303030303035363533100218012222313271796f6361794e46374c7636433971573461767873324537553431664b5366761a620805125e0a2d1080e0cd90f6a6ca342222313668747663424e53454137665a6841644c4a706844775152514a61487079485470122d1080aa83fff7a6ca342222313668747663424e53454137665a6841644c4a706844775152514a614870794854701a870108081282010a22313668747663424e53454137665a6841644c4a706844775152514a61487079485470122d1880f0cae386e68611222231344b454b6259744b4b516d34774d7468534b394a344c61346e41696964476f7a741a2d1880ba80d288e68611222231344b454b6259744b4b516d34774d7468534b394a344c61346e41696964476f7a741a620805125e0a2d1080aa83fff7a6ca342222313668747663424e53454137665a6841644c4a706844775152514a61487079485470122d1080f0898ef9a6ca342222313668747663424e53454137665a6841644c4a706844775152514a614870794854701a8f010808128a010a22313668747663424e53454137665a6841644c4a706844775152514a6148707948547012311080e0ba84bf03188090c0ac622222314251585336547861595947356d41446157696a344178685a5a55547077393561351a311080e0ba84bf031880d6c6bb632222314251585336547861595947356d41446157696a344178685a5a555470773935613512970208021a5c080212580a2a10c099b8c321222231513868474c666f47653633656665576138664a34506e756b686b6e677436706f4b122a10a08cb2c321222231513868474c666f47653633656665576138664a34506e756b686b6e677436706f4b1a82010809127e0a22313268704a4248796268316d537943696a51324d514a506b377a376b5a376a6e5161122a108094ebdc03222231513868474c666f47653633656665576138664a34506e756b686b6e677436706f4b1a2c109c93ebdc031864222231513868474c666f47653633656665576138664a34506e756b686b6e677436706f4b1a3008d301122b0a054142434445122231513868474c666f47653633656665576138664a34506e756b686b6e677436706f4b" 615 bs, err := hex.DecodeString(hexBlock) 616 if err != nil { 617 return nil 618 } 619 var block BlockDetail 620 err = Decode(bs, &block) 621 if err != nil { 622 return nil 623 } 624 return &block 625 } 626 627 //go test -run=none -bench=2Str -benchmem 628 func BenchmarkBytes2Str(b *testing.B) { 629 if testing.Short() { 630 b.Skip("skipping in short mode.") 631 } 632 buf := []byte{1, 2, 4, 8, 16, 32, 64, 128} 633 s := "" 634 b.ResetTimer() 635 636 b.Run("DirectBytes2Str", func(b *testing.B) { 637 for i := 0; i < b.N; i++ { 638 s = string(buf) 639 } 640 }) 641 642 b.Run("UnsafeBytes2Str", func(b *testing.B) { 643 for i := 0; i < b.N; i++ { 644 s = Bytes2Str(buf) 645 } 646 }) 647 648 assert.Equal(b, string(buf), s) 649 } 650 651 func BenchmarkStr2Bytes(b *testing.B) { 652 if testing.Short() { 653 b.Skip("skipping in short mode.") 654 } 655 s := "BenchmarkStr2Bytes" 656 var buf []byte 657 658 b.ResetTimer() 659 660 b.Run("DirectStr2Byte", func(b *testing.B) { 661 for i := 0; i < b.N; i++ { 662 buf = []byte(s) 663 } 664 }) 665 666 b.Run("UnsafeStr2Byte", func(b *testing.B) { 667 for i := 0; i < b.N; i++ { 668 buf = Str2Bytes(s) 669 } 670 }) 671 assert.Equal(b, []byte(s), buf) 672 }