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  }