Commit 9cd7511f authored by linj's avatar linj Committed by vipwzw

update-chain33

parent 94196411
......@@ -28,6 +28,10 @@ wget 127.0.0.1:8866 --no-proxy --post-data='{"id" : 1 , "method" : "ShowMinerAcc
1. 是否有某个挖矿帐号, 一个小时挖矿所得为0, 可能是挖矿机器出故障了
1. 增涨不到预期的50%
1. 不再监控这个点: 在预期能挖到币的两倍时间间隔内, 挖到的币为0。 挖矿有波动, 在进行预警的几天里, 这个有很多误报。
1. 数据获得失败报警
1. result 里面 null
1. 监控机器 heartbeat 表明监控机器没有宕机
```
{
"id" : 1,
......
......@@ -251,7 +251,7 @@ func TestSameTx(t *testing.T) {
func TestExecBlock(t *testing.T) {
mock33 := newMockNode()
defer mock33.Close()
block := util.CreateNoneBlock(mock33.GetGenesisKey(), 10)
block := util.CreateCoinsBlock(mock33.GetGenesisKey(), 1)
util.ExecBlock(mock33.GetClient(), nil, block, false, true)
}
......
......@@ -103,3 +103,21 @@ func TestNewParaClient(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, reply.Hash, []byte("hello"))
}
func TestNewMainChainClient(t *testing.T) {
grpcClient1, err := grpcclient.NewMainChainClient("")
assert.Nil(t, err)
grpcClient2, err := grpcclient.NewMainChainClient("")
assert.Nil(t, err)
if grpcClient1 != grpcClient2 {
t.Error("grpc client is the same")
}
grpcClient3, err := grpcclient.NewMainChainClient("127.0.0.1")
assert.Nil(t, err)
grpcClient4, err := grpcclient.NewMainChainClient("127.0.0.1")
assert.Nil(t, err)
if grpcClient3 == grpcClient4 {
t.Error("grpc client is not the same")
}
}
package grpcclient
import (
"sync"
"github.com/33cn/chain33/types"
"google.golang.org/grpc"
)
......@@ -8,8 +10,17 @@ import (
// paraChainGrpcRecSize 平行链receive最大100M
const paraChainGrpcRecSize = 100 * 1024 * 1024
var mu sync.Mutex
var defaultClient types.Chain33Client
//NewMainChainClient 创建一个平行链的 主链 grpc chain33 客户端
func NewMainChainClient(grpcaddr string) (types.Chain33Client, error) {
mu.Lock()
defer mu.Unlock()
if grpcaddr == "" && defaultClient != nil {
return defaultClient, nil
}
paraRemoteGrpcClient := types.Conf("config.consensus.sub.para").GStr("ParaRemoteGrpcClient")
if grpcaddr != "" {
paraRemoteGrpcClient = grpcaddr
......@@ -24,5 +35,8 @@ func NewMainChainClient(grpcaddr string) (types.Chain33Client, error) {
return nil, err
}
grpcClient := types.NewChain33Client(conn)
if grpcaddr == "" {
defaultClient = grpcClient
}
return grpcClient, nil
}
......@@ -14,7 +14,8 @@ import (
func TestMethodCall(t *testing.T) {
action := &CoinsAction{Value: &CoinsAction_Transfer{Transfer: &types.AssetsTransfer{}}}
funclist := types.ListMethod(action)
name, ty, v := types.GetActionValue(action, funclist)
name, ty, v, err := types.GetActionValue(action, funclist)
assert.Nil(t, err)
assert.Equal(t, int32(0), ty)
assert.Equal(t, "Transfer", name)
assert.Equal(t, &types.AssetsTransfer{}, v.Interface())
......@@ -44,9 +45,31 @@ func BenchmarkGetActionValue(b *testing.B) {
funclist := types.ListMethod(action)
b.ResetTimer()
for i := 0; i < b.N; i++ {
action, ty, _ := types.GetActionValue(action, funclist)
action, ty, _, _ := types.GetActionValue(action, funclist)
if action != "Transfer" || ty != 0 {
b.Fatal(action)
}
}
}
func BenchmarkDecodePayload(b *testing.B) {
action := &CoinsAction{Value: &CoinsAction_Transfer{Transfer: &types.AssetsTransfer{}}}
payload := types.Encode(action)
tx := &types.Transaction{Payload: payload}
ty := NewType()
b.ResetTimer()
for i := 0; i < b.N; i++ {
ty.DecodePayload(tx)
}
}
func BenchmarkDecodePayloadValue(b *testing.B) {
b.ReportAllocs()
action := &CoinsAction{Value: &CoinsAction_Transfer{Transfer: &types.AssetsTransfer{}}, Ty: CoinsActionTransfer}
payload := types.Encode(action)
tx := &types.Transaction{Payload: payload}
ty := NewType()
b.ResetTimer()
for i := 0; i < b.N; i++ {
ty.DecodePayloadValue(tx)
}
}
......@@ -5,6 +5,8 @@
package types
import (
"reflect"
"github.com/33cn/chain33/types"
)
......@@ -72,6 +74,50 @@ func (c *CoinsType) GetTypeMap() map[string]int32 {
return actionName
}
//DecodePayloadValue 为了性能考虑,coins 是最常用的合约,我们这里不用反射吗,做了特殊化的优化
func (c *CoinsType) DecodePayloadValue(tx *types.Transaction) (string, reflect.Value, error) {
if txc, ok := types.TxCacheGet(tx); ok {
return txc.GetPayloadValue()
}
txc := types.NewTransactionCache(tx)
name, value, err := c.decodePayloadValue(tx)
txc.SetPayloadValue(name, value, err)
types.TxCacheSet(tx, txc)
return name, value, err
}
func (c *CoinsType) decodePayloadValue(tx *types.Transaction) (string, reflect.Value, error) {
var action CoinsAction
if tx.GetPayload() == nil {
return "", reflect.ValueOf(nil), types.ErrActionNotSupport
}
err := types.Decode(tx.Payload, &action)
if err != nil {
return "", reflect.ValueOf(nil), err
}
var name string
var value types.Message
switch action.Ty {
case CoinsActionTransfer:
name = "Transfer"
value = action.GetTransfer()
case CoinsActionTransferToExec:
name = "TransferToExec"
value = action.GetTransferToExec()
case CoinsActionWithdraw:
name = "Withdraw"
value = action.GetWithdraw()
case CoinsActionGenesis:
name = "Genesis"
value = action.GetGenesis()
}
if value == nil {
return "", reflect.ValueOf(nil), types.ErrActionNotSupport
}
return name, reflect.ValueOf(value), nil
}
// RPC_Default_Process default process fo rpc
func (c *CoinsType) RPC_Default_Process(action string, msg interface{}) (*types.Transaction, error) {
var create *types.CreateTx
......
......@@ -422,7 +422,7 @@ func (base *ExecTypeBase) GetRealToAddr(tx *Transaction) string {
return tx.To
}
//平行链中的处理方式
_, v, err := base.DecodePayloadValue(tx)
_, v, err := base.child.DecodePayloadValue(tx)
if err != nil {
return tx.To
}
......@@ -468,7 +468,7 @@ type Amounter interface {
//Amount 获取tx交易中的转账金额
func (base *ExecTypeBase) Amount(tx *Transaction) (int64, error) {
_, v, err := base.DecodePayloadValue(tx)
_, v, err := base.child.DecodePayloadValue(tx)
if err != nil {
return 0, err
}
......@@ -503,14 +503,22 @@ func (base *ExecTypeBase) DecodePayload(tx *Transaction) (Message, error) {
if err != nil {
return nil, err
}
if IsNilP(payload) {
return nil, ErrDecode
}
return payload, nil
}
//DecodePayloadValue 解析tx交易中的payload具体Value值
func (base *ExecTypeBase) DecodePayloadValue(tx *Transaction) (string, reflect.Value, error) {
if txc, ok := txCache.Get(tx); ok {
return txc.(*TransactionCache).GetPayloadValue()
}
txc := NewTransactionCache(tx)
name, value, err := base.decodePayloadValue(tx)
txc.SetPayloadValue(name, value, err)
txCache.Add(tx, txc)
return name, value, err
}
func (base *ExecTypeBase) decodePayloadValue(tx *Transaction) (string, reflect.Value, error) {
if base.child == nil {
return "", nilValue, ErrActionNotSupport
}
......@@ -519,10 +527,9 @@ func (base *ExecTypeBase) DecodePayloadValue(tx *Transaction) (string, reflect.V
tlog.Error("DecodePayload", "err", err, "exec", string(tx.Execer))
return "", nilValue, err
}
name, ty, val := GetActionValue(action, base.child.GetFuncMap())
if IsNil(val) {
tlog.Error("GetActionValue is nil")
return "", nilValue, ErrActionNotSupport
name, ty, val, err := GetActionValue(action, base.child.GetFuncMap())
if err != nil {
return "", nilValue, err
}
typemap := base.child.GetTypeMap()
//check types is ok
......@@ -769,7 +776,7 @@ func (base *ExecTypeBase) CreateTransaction(action string, data Message) (tx *Tr
// GetAssets 获取资产信息
func (base *ExecTypeBase) GetAssets(tx *Transaction) ([]*Asset, error) {
_, v, err := base.DecodePayloadValue(tx)
_, v, err := base.child.DecodePayloadValue(tx)
if err != nil {
return nil, err
}
......
......@@ -95,12 +95,13 @@ func ListMethodByType(typ reflect.Type) map[string]reflect.Method {
var nilValue = reflect.ValueOf(nil)
// GetActionValue 获取执行器的action value
func GetActionValue(action interface{}, funclist map[string]reflect.Method) (vname string, vty int32, v reflect.Value) {
func GetActionValue(action interface{}, funclist map[string]reflect.Method) (vname string, vty int32, v reflect.Value, err error) {
defer func() {
if e := recover(); e != nil {
vname = ""
vty = 0
v = nilValue
err = ErrDecode
}
}()
var ty int32
......@@ -109,22 +110,25 @@ func GetActionValue(action interface{}, funclist map[string]reflect.Method) (vna
}
value := reflect.ValueOf(action)
if _, ok := funclist["GetValue"]; !ok {
return "", 0, nilValue
return "", 0, nilValue, ErrDecode
}
rcvr := funclist["GetValue"].Func.Call([]reflect.Value{value})
elem := rcvr[0].Elem()
sname := elem.Type().String()
index := strings.LastIndex(sname, "_")
if index == -1 || index == (len(sname)-1) {
return "", 0, nilValue
return "", 0, nilValue, ErrDecode
}
tyname := sname[index+1:]
funcname := "Get" + tyname
if _, ok := funclist[funcname]; !ok {
return "", 0, nilValue
return "", 0, nilValue, ErrDecode
}
val := funclist[funcname].Func.Call([]reflect.Value{value})
return tyname, ty, val[0]
if len(val) == 0 || val[0].IsNil() {
return "", 0, nilValue, ErrDecode
}
return tyname, ty, val[0], nil
}
// IsOK 是否存在
......
......@@ -8,8 +8,11 @@ import (
"bytes"
"encoding/hex"
"encoding/json"
"reflect"
"time"
"github.com/hashicorp/golang-lru"
"strconv"
"github.com/33cn/chain33/common"
......@@ -21,8 +24,35 @@ var (
bCoins = []byte("coins")
bToken = []byte("token")
withdraw = "withdraw"
txCache *lru.Cache
)
func init() {
var err error
txCache, err = lru.New(10240)
if err != nil {
panic(err)
}
}
//TxCacheGet 某些交易的cache 加入缓存中,防止重复进行解析或者计算
func TxCacheGet(tx *Transaction) (*TransactionCache, bool) {
txc, ok := txCache.Get(tx)
if !ok {
return nil, ok
}
return txc.(*TransactionCache), ok
}
//TxCacheSet 设置 cache
func TxCacheSet(tx *Transaction, txc *TransactionCache) {
if txc == nil {
txCache.Remove(tx)
return
}
txCache.Add(tx, txc)
}
// CreateTxGroup 创建组交易
func CreateTxGroup(txs []*Transaction) (*Transactions, error) {
if len(txs) < 2 {
......@@ -204,6 +234,9 @@ type TransactionCache struct {
signok int //init 0, ok 1, err 2
checkok error //init 0, ok 1, err 2
checked bool
payload reflect.Value
plname string
plerr error
}
//NewTransactionCache new交易缓存
......@@ -219,6 +252,28 @@ func (tx *TransactionCache) Hash() []byte {
return tx.hash
}
//SetPayloadValue 设置payload 的cache
func (tx *TransactionCache) SetPayloadValue(plname string, payload reflect.Value, plerr error) {
tx.payload = payload
tx.plerr = plerr
tx.plname = plname
}
//GetPayloadValue 设置payload 的cache
func (tx *TransactionCache) GetPayloadValue() (plname string, payload reflect.Value, plerr error) {
if tx.plerr != nil || tx.plname != "" {
return tx.plname, tx.payload, tx.plerr
}
exec := LoadExecutorType(string(tx.Execer))
if exec == nil {
tx.SetPayloadValue("", reflect.ValueOf(nil), ErrExecNotFound)
return "", reflect.ValueOf(nil), ErrExecNotFound
}
plname, payload, plerr = exec.DecodePayloadValue(tx.Tx())
tx.SetPayloadValue(plname, payload, plerr)
return
}
//Size 交易缓存的大小
func (tx *TransactionCache) Size() int {
if tx.size == 0 {
......
......@@ -289,15 +289,15 @@ func (mock *Chain33Mock) Close() {
}
func (mock *Chain33Mock) closeNoLock() {
mock.chain.Close()
mock.store.Close()
mock.network.Close()
mock.rpc.Close()
mock.mem.Close()
mock.cs.Close()
mock.exec.Close()
mock.cs.Close()
mock.wallet.Close()
mock.network.Close()
mock.chain.Close()
mock.store.Close()
mock.client.Close()
mock.rpc.Close()
os.RemoveAll(mock.datadir)
}
......
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