Commit d4c248a9 authored by heyubin's avatar heyubin

add by hyb for conflicts

parents 8bc5b25a 95a394d8
...@@ -12,7 +12,7 @@ require ( ...@@ -12,7 +12,7 @@ require (
github.com/NebulousLabs/merkletree v0.0.0-20181203152040-08d5d54b07f5 // indirect github.com/NebulousLabs/merkletree v0.0.0-20181203152040-08d5d54b07f5 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
github.com/bitly/go-simplejson v0.5.0 github.com/bitly/go-simplejson v0.5.0
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/btcsuite/btcd v0.20.1-beta github.com/btcsuite/btcd v0.20.1-beta
github.com/coreos/etcd v3.3.15+incompatible github.com/coreos/etcd v3.3.15+incompatible
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect
......
This diff is collapsed.
...@@ -19,7 +19,6 @@ import ( ...@@ -19,7 +19,6 @@ import (
"github.com/33cn/chain33/common/limits" "github.com/33cn/chain33/common/limits"
"github.com/33cn/chain33/common/log" "github.com/33cn/chain33/common/log"
"github.com/33cn/chain33/executor" "github.com/33cn/chain33/executor"
"github.com/33cn/chain33/mempool"
"github.com/33cn/chain33/p2p" "github.com/33cn/chain33/p2p"
"github.com/33cn/chain33/queue" "github.com/33cn/chain33/queue"
"github.com/33cn/chain33/store" "github.com/33cn/chain33/store"
...@@ -47,9 +46,8 @@ func init() { ...@@ -47,9 +46,8 @@ func init() {
log.SetLogLevel("info") log.SetLogLevel("info")
} }
func TestPbft(t *testing.T) { func TestPbft(t *testing.T) {
q, chain, p2pnet, s, mem, exec, cs, wallet := initEnvPbft() q, chain, p2pnet, s, exec, cs, wallet := initEnvPbft()
defer chain.Close() defer chain.Close()
defer mem.Close()
defer p2pnet.Close() defer p2pnet.Close()
defer exec.Close() defer exec.Close()
defer s.Close() defer s.Close()
...@@ -62,7 +60,7 @@ func TestPbft(t *testing.T) { ...@@ -62,7 +60,7 @@ func TestPbft(t *testing.T) {
clearTestData() clearTestData()
} }
func initEnvPbft() (queue.Queue, *blockchain.BlockChain, *p2p.Manager, queue.Module, queue.Module, *executor.Executor, queue.Module, queue.Module) { func initEnvPbft() (queue.Queue, *blockchain.BlockChain, *p2p.Manager, queue.Module, *executor.Executor, queue.Module, queue.Module) {
flag.Parse() flag.Parse()
chain33Cfg := types.NewChain33Config(types.ReadFile("chain33.test.toml")) chain33Cfg := types.NewChain33Config(types.ReadFile("chain33.test.toml"))
var q = queue.New("channel") var q = queue.New("channel")
...@@ -72,8 +70,6 @@ func initEnvPbft() (queue.Queue, *blockchain.BlockChain, *p2p.Manager, queue.Mod ...@@ -72,8 +70,6 @@ func initEnvPbft() (queue.Queue, *blockchain.BlockChain, *p2p.Manager, queue.Mod
chain := blockchain.New(chain33Cfg) chain := blockchain.New(chain33Cfg)
chain.SetQueueClient(q.Client()) chain.SetQueueClient(q.Client())
mem := mempool.New(chain33Cfg)
mem.SetQueueClient(q.Client())
exec := executor.New(chain33Cfg) exec := executor.New(chain33Cfg)
exec.SetQueueClient(q.Client()) exec.SetQueueClient(q.Client())
chain33Cfg.SetMinFee(0) chain33Cfg.SetMinFee(0)
...@@ -86,7 +82,7 @@ func initEnvPbft() (queue.Queue, *blockchain.BlockChain, *p2p.Manager, queue.Mod ...@@ -86,7 +82,7 @@ func initEnvPbft() (queue.Queue, *blockchain.BlockChain, *p2p.Manager, queue.Mod
walletm := wallet.New(chain33Cfg) walletm := wallet.New(chain33Cfg)
walletm.SetQueueClient(q.Client()) walletm.SetQueueClient(q.Client())
return q, chain, p2pnet, s, mem, exec, cs, walletm return q, chain, p2pnet, s, exec, cs, walletm
} }
...@@ -104,6 +100,8 @@ func sendReplyList(q queue.Queue) { ...@@ -104,6 +100,8 @@ func sendReplyList(q queue.Queue) {
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
break break
} }
} else if msg.Ty == types.EventGetMempoolSize {
msg.Reply(client.NewMessage("", 0, &types.MempoolSize{}))
} }
} }
} }
......
...@@ -74,7 +74,6 @@ func (w *Wasm) Exec_Create(payload *types2.WasmCreate, tx *types.Transaction, in ...@@ -74,7 +74,6 @@ func (w *Wasm) Exec_Create(payload *types2.WasmCreate, tx *types.Transaction, in
} }
func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index int) (*types.Receipt, error) { func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index int) (*types.Receipt, error) {
log.Info("into wasm Exec_Call...")
if payload == nil { if payload == nil {
return nil, types.ErrInvalidParam return nil, types.ErrInvalidParam
} }
...@@ -83,11 +82,14 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index ...@@ -83,11 +82,14 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index
} }
w.stateKVC = dapp.NewKVCreator(w.GetStateDB(), calcStatePrefix(payload.Contract), nil) w.stateKVC = dapp.NewKVCreator(w.GetStateDB(), calcStatePrefix(payload.Contract), nil)
var vm *exec.VirtualMachine
var ok bool
if vm, ok = w.VMCache[payload.Contract]; !ok {
code, err := w.stateKVC.GetNoPrefix(contractKey(payload.Contract)) code, err := w.stateKVC.GetNoPrefix(contractKey(payload.Contract))
if err != nil { if err != nil {
return nil, err return nil, err
} }
vm, err := exec.NewVirtualMachine(code, exec.VMConfig{ vm, err = exec.NewVirtualMachine(code, exec.VMConfig{
DefaultMemoryPages: 128, DefaultMemoryPages: 128,
DefaultTableSize: 128, DefaultTableSize: 128,
DisableFloatingPoint: true, DisableFloatingPoint: true,
...@@ -96,6 +98,11 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index ...@@ -96,6 +98,11 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index
if err != nil { if err != nil {
return nil, err return nil, err
} }
w.VMCache[payload.Contract] = vm
} else {
vm.Config.GasLimit = uint64(tx.Fee)
vm.Gas = 0
}
// Get the function ID of the entry function to be executed. // Get the function ID of the entry function to be executed.
entryID, ok := vm.GetFunctionExport(payload.Method) entryID, ok := vm.GetFunctionExport(payload.Method)
...@@ -115,7 +122,6 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index ...@@ -115,7 +122,6 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index
if err != nil { if err != nil {
return nil, err return nil, err
} }
var kvs []*types.KeyValue var kvs []*types.KeyValue
kvs = append(kvs, w.kvs...) kvs = append(kvs, w.kvs...)
kvs = append(kvs, w.stateKVC.KVList()...) kvs = append(kvs, w.stateKVC.KVList()...)
...@@ -124,7 +130,7 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index ...@@ -124,7 +130,7 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index
logs = append(logs, &types.ReceiptLog{Ty: types2.TyLogWasmCall, Log: types.Encode(&types2.CallContractLog{ logs = append(logs, &types.ReceiptLog{Ty: types2.TyLogWasmCall, Log: types.Encode(&types2.CallContractLog{
Contract: payload.Contract, Contract: payload.Contract,
Method: payload.Method, Method: payload.Method,
Result: ret, Result: int32(ret),
})}) })})
logs = append(logs, w.receiptLogs...) logs = append(logs, w.receiptLogs...)
logs = append(logs, &types.ReceiptLog{Ty: types2.TyLogCustom, Log: types.Encode(&types2.CustomLog{ logs = append(logs, &types.ReceiptLog{Ty: types2.TyLogCustom, Log: types.Encode(&types2.CustomLog{
...@@ -142,7 +148,7 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index ...@@ -142,7 +148,7 @@ func (w *Wasm) Exec_Call(payload *types2.WasmCall, tx *types.Transaction, index
KV: kvs, KV: kvs,
Logs: logs, Logs: logs,
} }
if ret < 0 { if int32(ret) < 0 || int16(ret) < 0 {
receipt.Ty = types.ExecPack receipt.Ty = types.ExecPack
} }
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
drivers "github.com/33cn/chain33/system/dapp" drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
types2 "github.com/33cn/plugin/plugin/dapp/wasm/types" types2 "github.com/33cn/plugin/plugin/dapp/wasm/types"
"github.com/perlin-network/life/exec"
) )
var driverName = types2.WasmX var driverName = types2.WasmX
...@@ -36,10 +37,13 @@ type Wasm struct { ...@@ -36,10 +37,13 @@ type Wasm struct {
customLogs []string customLogs []string
execAddr string execAddr string
contractName string contractName string
VMCache map[string]*exec.VirtualMachine
} }
func newWasm() drivers.Driver { func newWasm() drivers.Driver {
d := &Wasm{} d := &Wasm{
VMCache: make(map[string]*exec.VirtualMachine),
}
d.SetChild(d) d.SetChild(d)
d.SetExecutorType(types.LoadExecutorType(driverName)) d.SetExecutorType(types.LoadExecutorType(driverName))
return d return d
......
package executor package executor
import ( import (
"encoding/hex"
"io/ioutil" "io/ioutil"
"strings" "strings"
"testing" "testing"
...@@ -41,10 +42,54 @@ func init() { ...@@ -41,10 +42,54 @@ func init() {
Init(types2.WasmX, cfg, nil) Init(types2.WasmX, cfg, nil)
} }
func BenchmarkWasm_Exec_Call(b *testing.B) {
dir, ldb, kvdb := util.CreateTestDB()
defer util.CloseTestDB(dir, ldb)
acc := initAccount(ldb)
testCreate(b, acc, kvdb)
testCall(b, acc, kvdb)
payload := types2.WasmAction{
Ty: types2.WasmActionCall,
Value: &types2.WasmAction_Call{
Call: &types2.WasmCall{
Contract: "dice",
Method: "play",
Parameters: []int64{1, 10},
},
},
}
tx := &types.Transaction{
Payload: types.Encode(&payload),
}
tx, err := types.FormatTx(cfg, types2.WasmX, tx)
require.Nil(b, err, "format tx error")
err = signTx(tx, PrivKeys[1])
require.Nil(b, err)
wasm := newWasm()
wasm.SetCoinsAccount(acc)
wasm.SetStateDB(kvdb)
api := mocks.QueueProtocolAPI{}
api.On("GetConfig").Return(cfg)
api.On("GetRandNum", mock.Anything).Return(hex.DecodeString("0x0b1f047927e1c42327bdd3222558eaf7b10b998e7a9bb8144e4b2a27ffa53df3"))
wasm.SetAPI(&api)
wasmCB = wasm.(*Wasm)
err = transferToExec(Addrs[1], wasmAddr, 1e9)
require.Nil(b, err)
wasmCB = nil
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := wasm.Exec(tx, 0)
require.Nil(b, err)
}
b.StopTimer()
}
func TestWasm_Exec(t *testing.T) { func TestWasm_Exec(t *testing.T) {
dir, ldb, kvdb := util.CreateTestDB() dir, ldb, kvdb := util.CreateTestDB()
defer util.CloseTestDB(dir, ldb) defer util.CloseTestDB(dir, ldb)
acc := initAccount(t, ldb) acc := initAccount(ldb)
testCreate(t, acc, kvdb) testCreate(t, acc, kvdb)
testCall(t, acc, kvdb) testCall(t, acc, kvdb)
...@@ -54,7 +99,7 @@ func TestWasm_Callback(t *testing.T) { ...@@ -54,7 +99,7 @@ func TestWasm_Callback(t *testing.T) {
dir, ldb, kvdb := util.CreateTestDB() dir, ldb, kvdb := util.CreateTestDB()
defer util.CloseTestDB(dir, ldb) defer util.CloseTestDB(dir, ldb)
wasmCB = newWasm().(*Wasm) wasmCB = newWasm().(*Wasm)
acc := initAccount(t, ldb) acc := initAccount(ldb)
wasmCB.SetCoinsAccount(acc) wasmCB.SetCoinsAccount(acc)
wasmCB.SetStateDB(kvdb) wasmCB.SetStateDB(kvdb)
wasmCB.SetLocalDB(kvdb) wasmCB.SetLocalDB(kvdb)
...@@ -218,7 +263,7 @@ func TestWasm_Callback(t *testing.T) { ...@@ -218,7 +263,7 @@ func TestWasm_Callback(t *testing.T) {
t.Log(random) t.Log(random)
} }
func testCreate(t *testing.T, acc *account.DB, stateDB db.KV) { func testCreate(t testing.TB, acc *account.DB, stateDB db.KV) {
code, err := ioutil.ReadFile("../contracts/dice/dice.wasm") code, err := ioutil.ReadFile("../contracts/dice/dice.wasm")
require.Nil(t, err, "read wasm file error") require.Nil(t, err, "read wasm file error")
payload := types2.WasmAction{ payload := types2.WasmAction{
...@@ -253,7 +298,7 @@ func testCreate(t *testing.T, acc *account.DB, stateDB db.KV) { ...@@ -253,7 +298,7 @@ func testCreate(t *testing.T, acc *account.DB, stateDB db.KV) {
require.Nil(t, err) require.Nil(t, err)
} }
func testCall(t *testing.T, acc *account.DB, stateDB db.KV) { func testCall(t testing.TB, acc *account.DB, stateDB db.KV) {
payload := types2.WasmAction{ payload := types2.WasmAction{
Ty: types2.WasmActionCall, Ty: types2.WasmActionCall,
Value: &types2.WasmAction_Call{ Value: &types2.WasmAction_Call{
...@@ -287,10 +332,12 @@ func testCall(t *testing.T, acc *account.DB, stateDB db.KV) { ...@@ -287,10 +332,12 @@ func testCall(t *testing.T, acc *account.DB, stateDB db.KV) {
require.Equal(t, int32(types2.TyLogWasmCall), receipt.Logs[0].Ty) require.Equal(t, int32(types2.TyLogWasmCall), receipt.Logs[0].Ty)
} }
func initAccount(t *testing.T, db db.KV) *account.DB { func initAccount(db db.KV) *account.DB {
wasmAddr = address.ExecAddress(cfg.ExecName(types2.WasmX)) wasmAddr = address.ExecAddress(cfg.ExecName(types2.WasmX))
acc, err := account.NewAccountDB(cfg, "coins", "bty", db) acc, err := account.NewAccountDB(cfg, "coins", "bty", db)
require.Nil(t, err, "new account db error") if err != nil {
panic(err)
}
acc.SaveAccount(&types.Account{ acc.SaveAccount(&types.Account{
Balance: 1e10, Balance: 1e10,
Addr: Addrs[0], Addr: Addrs[0],
......
...@@ -37,7 +37,7 @@ message createContractLog { ...@@ -37,7 +37,7 @@ message createContractLog {
message callContractLog { message callContractLog {
string contract = 1; string contract = 1;
string method = 2; string method = 2;
int64 result = 3; int32 result = 3;
} }
message localDataLog { message localDataLog {
......
...@@ -339,7 +339,7 @@ func (m *CreateContractLog) GetCode() string { ...@@ -339,7 +339,7 @@ func (m *CreateContractLog) GetCode() string {
type CallContractLog struct { type CallContractLog struct {
Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"` Contract string `protobuf:"bytes,1,opt,name=contract,proto3" json:"contract,omitempty"`
Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"` Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"`
Result int64 `protobuf:"varint,3,opt,name=result,proto3" json:"result,omitempty"` Result int32 `protobuf:"varint,3,opt,name=result,proto3" json:"result,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
...@@ -384,7 +384,7 @@ func (m *CallContractLog) GetMethod() string { ...@@ -384,7 +384,7 @@ func (m *CallContractLog) GetMethod() string {
return "" return ""
} }
func (m *CallContractLog) GetResult() int64 { func (m *CallContractLog) GetResult() int32 {
if m != nil { if m != nil {
return m.Result return m.Result
} }
...@@ -454,26 +454,26 @@ func init() { ...@@ -454,26 +454,26 @@ func init() {
} }
var fileDescriptor_7d78909ad64e3bbb = []byte{ var fileDescriptor_7d78909ad64e3bbb = []byte{
// 328 bytes of a gzipped FileDescriptorProto // 327 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0x31, 0x4f, 0xc3, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0x4f, 0x4b, 0xc3, 0x40,
0x10, 0x85, 0x9b, 0xba, 0x0d, 0xcd, 0x51, 0x51, 0x6a, 0xa1, 0x2a, 0x62, 0x80, 0xc8, 0x12, 0x52, 0x10, 0xc5, 0x9b, 0xa6, 0x8d, 0xcd, 0x58, 0xac, 0x5d, 0xa4, 0x04, 0x0f, 0x1a, 0x16, 0x84, 0x80,
0x24, 0xa4, 0x0e, 0x80, 0x58, 0x98, 0xa0, 0x0c, 0x1d, 0x98, 0xbc, 0x83, 0x64, 0x5c, 0x43, 0xab, 0xd0, 0x83, 0x8a, 0x17, 0x4f, 0x5a, 0x0f, 0x3d, 0x78, 0xda, 0xbb, 0xc2, 0xba, 0x5d, 0x6d, 0xe9,
0x3a, 0x71, 0x71, 0x2e, 0xa0, 0xfc, 0x7b, 0x64, 0xc7, 0x45, 0x19, 0x10, 0x03, 0xdb, 0xdd, 0xf9, 0x26, 0x5b, 0x37, 0x13, 0x25, 0xdf, 0x5e, 0xf6, 0x4f, 0x25, 0x07, 0xf1, 0xe0, 0x6d, 0x66, 0xf6,
0xbb, 0xf7, 0x72, 0x77, 0x01, 0xf8, 0x12, 0x55, 0x31, 0xdf, 0x59, 0x83, 0x86, 0x0e, 0xb1, 0xd9, 0x37, 0xef, 0x65, 0x66, 0x02, 0xf0, 0xc5, 0xeb, 0x72, 0xbe, 0x33, 0x1a, 0x35, 0x19, 0x62, 0xbb,
0xa9, 0x8a, 0x35, 0x6d, 0xf1, 0x5e, 0xe2, 0xc6, 0x94, 0xf4, 0x12, 0x62, 0x69, 0x95, 0x40, 0x95, 0x93, 0x35, 0x6d, 0x7d, 0xf1, 0x5e, 0xe0, 0x46, 0x57, 0xe4, 0x12, 0x12, 0x61, 0x24, 0x47, 0x99,
0x46, 0x59, 0x94, 0x1f, 0x5e, 0x4d, 0xe7, 0x9e, 0x9a, 0x3b, 0x64, 0xe1, 0x1f, 0x96, 0x3d, 0x1e, 0x45, 0x79, 0x54, 0x1c, 0x5e, 0x4d, 0xe7, 0x8e, 0x9a, 0x5b, 0x64, 0xe1, 0x1e, 0x96, 0x3d, 0x16,
0x10, 0x7a, 0x01, 0x03, 0x29, 0xb4, 0x4e, 0xfb, 0x1e, 0x9d, 0x74, 0x51, 0xa1, 0xf5, 0xb2, 0xc7, 0x10, 0x72, 0x01, 0x03, 0xc1, 0x95, 0xca, 0xfa, 0x0e, 0x9d, 0x74, 0x51, 0xae, 0xd4, 0xb2, 0xc7,
0xfd, 0x33, 0x3d, 0x82, 0x3e, 0x36, 0x29, 0xc9, 0xa2, 0x7c, 0xc8, 0xfb, 0xd8, 0x3c, 0x1c, 0xc0, 0xdc, 0x33, 0x39, 0x82, 0x3e, 0xb6, 0x59, 0x9c, 0x47, 0xc5, 0x90, 0xf5, 0xb1, 0x7d, 0x38, 0x80,
0xf0, 0x53, 0xe8, 0x5a, 0xb1, 0x9b, 0xd6, 0xba, 0xd5, 0xa5, 0x14, 0x06, 0xa5, 0x28, 0x5a, 0xe3, 0xe1, 0x27, 0x57, 0x8d, 0xa4, 0x37, 0xde, 0xda, 0xeb, 0x12, 0x02, 0x83, 0x8a, 0x97, 0xde, 0x38,
0x84, 0xfb, 0xd8, 0xd5, 0xa4, 0x59, 0x29, 0xef, 0x30, 0xe6, 0x3e, 0x66, 0x2f, 0x30, 0xda, 0x5b, 0x65, 0x2e, 0xb6, 0x35, 0xa1, 0x57, 0xd2, 0x39, 0x8c, 0x99, 0x8b, 0xe9, 0x0b, 0x8c, 0xf6, 0x16,
0xd0, 0x53, 0x18, 0x49, 0x53, 0xa2, 0x15, 0x12, 0x43, 0xdf, 0x4f, 0x4e, 0x67, 0x10, 0x17, 0x0a, 0xe4, 0x14, 0x46, 0x42, 0x57, 0x68, 0xb8, 0xc0, 0xd0, 0xf7, 0x93, 0x93, 0x19, 0x24, 0xa5, 0xc4,
0xd7, 0x66, 0xe5, 0xbb, 0x13, 0x1e, 0x32, 0x7a, 0x06, 0xb0, 0x13, 0x56, 0x14, 0x0a, 0x95, 0xad, 0xb5, 0x5e, 0xb9, 0xee, 0x94, 0x85, 0x8c, 0x9c, 0x01, 0xec, 0xb8, 0xe1, 0xa5, 0x44, 0x69, 0xea,
0x52, 0x92, 0x91, 0x9c, 0xf0, 0x4e, 0x85, 0xe5, 0x40, 0x3f, 0x6a, 0x65, 0x9b, 0xc5, 0x5a, 0xc9, 0x2c, 0xce, 0xe3, 0x22, 0x66, 0x9d, 0x0a, 0x2d, 0x80, 0x7c, 0x34, 0xd2, 0xb4, 0x8b, 0xb5, 0x14,
0xed, 0x62, 0xaf, 0xf6, 0xcb, 0xd7, 0xb1, 0x73, 0x48, 0x64, 0x5d, 0xa1, 0x29, 0x9e, 0xcc, 0xbb, 0xdb, 0xc5, 0x5e, 0xed, 0x97, 0xaf, 0xa3, 0xe7, 0x90, 0x8a, 0xa6, 0x46, 0x5d, 0x3e, 0xe9, 0x77,
0x03, 0x36, 0xe5, 0x9b, 0x49, 0xa3, 0x8c, 0x38, 0xc0, 0xc5, 0xec, 0x0e, 0xa6, 0xed, 0xaa, 0xf6, 0x0b, 0x6c, 0xaa, 0x37, 0x9d, 0x45, 0x79, 0x6c, 0x01, 0x1b, 0xd3, 0x3b, 0x98, 0xfa, 0x55, 0xed,
0x32, 0x01, 0xfc, 0x73, 0xce, 0x24, 0xcc, 0xf9, 0x0c, 0x13, 0xb7, 0xbe, 0x6e, 0xeb, 0x7f, 0xc6, 0x65, 0x02, 0xf8, 0xe7, 0x9c, 0x69, 0x98, 0xf3, 0x19, 0x26, 0x76, 0x7d, 0xdd, 0xd6, 0xff, 0x8c,
0x9d, 0x41, 0x6c, 0x55, 0x55, 0x6b, 0xf4, 0x17, 0x20, 0x3c, 0x64, 0xec, 0x16, 0xc6, 0xda, 0x48, 0x3b, 0x83, 0xc4, 0xc8, 0xba, 0x51, 0x18, 0x2e, 0x10, 0x32, 0x7a, 0x0b, 0x63, 0xa5, 0x05, 0x57,
0xa1, 0x1f, 0x05, 0x0a, 0xa7, 0x7d, 0x0c, 0x64, 0xab, 0x1a, 0x2f, 0x3b, 0xe6, 0x2e, 0xa4, 0x27, 0x8f, 0x1c, 0xb9, 0xd5, 0x3e, 0x86, 0x78, 0x2b, 0x5b, 0x27, 0x3b, 0x66, 0x36, 0x24, 0x27, 0xe1,
0xe1, 0x4e, 0x61, 0xfb, 0x6d, 0xf2, 0x1a, 0xfb, 0xbf, 0xe7, 0xfa, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x4e, 0x61, 0xfb, 0x3e, 0x79, 0x4d, 0xdc, 0xdf, 0x73, 0xfd, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xc3,
0x24, 0x00, 0xa4, 0xe6, 0x4b, 0x02, 0x00, 0x00, 0xc2, 0x9e, 0xbb, 0x4b, 0x02, 0x00, 0x00,
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment