github.com/turingchain2020/turingchain@v1.1.21/rpc/jrpchandler.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 rpc
     6  
     7  import (
     8  	"bytes"
     9  	"context"
    10  	"encoding/hex"
    11  	"encoding/json"
    12  	"strconv"
    13  	"time"
    14  
    15  	"github.com/turingchain2020/turingchain/common"
    16  	"github.com/turingchain2020/turingchain/common/address"
    17  	rpctypes "github.com/turingchain2020/turingchain/rpc/types"
    18  	"github.com/turingchain2020/turingchain/types"
    19  	wcom "github.com/turingchain2020/turingchain/wallet/common"
    20  )
    21  
    22  // CreateRawTransaction create rawtransaction by jrpc
    23  func (c *Turingchain) CreateRawTransaction(in *rpctypes.CreateTx, result *interface{}) error {
    24  	if in == nil {
    25  		log.Error("CreateRawTransaction", "Error", types.ErrInvalidParam)
    26  		return types.ErrInvalidParam
    27  	}
    28  	inpb := &types.CreateTx{
    29  		To:          in.To,
    30  		Amount:      in.Amount,
    31  		Fee:         in.Fee,
    32  		Note:        []byte(in.Note),
    33  		IsWithdraw:  in.IsWithdraw,
    34  		IsToken:     in.IsToken,
    35  		TokenSymbol: in.TokenSymbol,
    36  		ExecName:    in.ExecName,
    37  		Execer:      in.Execer,
    38  	}
    39  	reply, err := c.cli.CreateRawTransaction(inpb)
    40  	if err != nil {
    41  		return err
    42  	}
    43  	*result = common.ToHex(reply)
    44  	return nil
    45  }
    46  
    47  // ReWriteRawTx re-write raw tx by jrpc
    48  func (c *Turingchain) ReWriteRawTx(in *rpctypes.ReWriteRawTx, result *interface{}) error {
    49  	inpb := &types.ReWriteRawTx{
    50  		Tx:     in.Tx,
    51  		To:     in.To,
    52  		Fee:    in.Fee,
    53  		Expire: in.Expire,
    54  		Index:  in.Index,
    55  	}
    56  
    57  	reply, err := c.cli.ReWriteRawTx(inpb)
    58  	if err != nil {
    59  		return err
    60  	}
    61  	*result = common.ToHex(reply)
    62  	return nil
    63  }
    64  
    65  // CreateRawTxGroup create rawtransaction with group
    66  func (c *Turingchain) CreateRawTxGroup(in *types.CreateTransactionGroup, result *interface{}) error {
    67  	reply, err := c.cli.CreateRawTxGroup(in)
    68  	if err != nil {
    69  		return err
    70  	}
    71  
    72  	*result = common.ToHex(reply)
    73  	return nil
    74  }
    75  
    76  // CreateNoBlanaceTxs create multiple transaction with no balance
    77  func (c *Turingchain) CreateNoBlanaceTxs(in *types.NoBalanceTxs, result *string) error {
    78  	tx, err := c.cli.CreateNoBalanceTxs(in)
    79  	if err != nil {
    80  		return err
    81  	}
    82  	grouptx := common.ToHex(types.Encode(tx))
    83  	*result = grouptx
    84  	return nil
    85  }
    86  
    87  // CreateNoBalanceTransaction create transaction with no balance
    88  func (c *Turingchain) CreateNoBalanceTransaction(in *types.NoBalanceTx, result *string) error {
    89  	params := &types.NoBalanceTxs{
    90  		TxHexs:  []string{in.GetTxHex()},
    91  		PayAddr: in.GetPayAddr(),
    92  		Privkey: in.GetPrivkey(),
    93  		Expire:  in.GetExpire(),
    94  	}
    95  	tx, err := c.cli.CreateNoBalanceTxs(params)
    96  	if err != nil {
    97  		return err
    98  	}
    99  	grouptx := common.ToHex(types.Encode(tx))
   100  	*result = grouptx
   101  	return nil
   102  }
   103  
   104  // SendTransaction send transaction
   105  func (c *Turingchain) SendTransaction(in rpctypes.RawParm, result *interface{}) error {
   106  	var parm types.Transaction
   107  	data, err := common.FromHex(in.Data)
   108  	if err != nil {
   109  		return err
   110  	}
   111  	err = types.Decode(data, &parm)
   112  	if err != nil {
   113  		return err
   114  	}
   115  	log.Debug("SendTransaction", "parm", parm)
   116  
   117  	var reply *types.Reply
   118  	//para chain, forward to main chain
   119  	cfg := c.cli.GetConfig()
   120  	if cfg.IsPara() {
   121  		reply, err = c.mainGrpcCli.SendTransaction(context.Background(), &parm)
   122  	} else {
   123  		reply, err = c.cli.SendTx(&parm)
   124  	}
   125  
   126  	if err == nil {
   127  		*result = common.ToHex(reply.GetMsg())
   128  	}
   129  	return err
   130  }
   131  
   132  // SendTransactionSync send transaction and wait reply
   133  func (c *Turingchain) SendTransactionSync(in rpctypes.RawParm, result *interface{}) error {
   134  	err := c.SendTransaction(in, result)
   135  	if err != nil {
   136  		return err
   137  	}
   138  	hash := (*result).(string)
   139  	param := rpctypes.QueryParm{Hash: hash}
   140  	var res interface{}
   141  	for i := 0; i < 100; i++ {
   142  		err = c.QueryTransaction(param, &res)
   143  		if err == types.ErrInvalidParam || err == types.ErrTypeAsset {
   144  			return err
   145  		}
   146  		if _, ok := (res).(*rpctypes.TransactionDetail); ok {
   147  			return nil
   148  		}
   149  		time.Sleep(time.Second / 3)
   150  	}
   151  
   152  	return types.ErrTimeout
   153  }
   154  
   155  // GetHexTxByHash get hex transaction by hash
   156  func (c *Turingchain) GetHexTxByHash(in rpctypes.QueryParm, result *interface{}) error {
   157  	var data types.ReqHash
   158  	hash, err := common.FromHex(in.Hash)
   159  	if err != nil {
   160  		return err
   161  	}
   162  	data.Hash = hash
   163  	reply, err := c.cli.QueryTx(&data)
   164  	if err != nil {
   165  		return err
   166  	}
   167  	*result = common.ToHex(types.Encode(reply.GetTx()))
   168  	return err
   169  }
   170  
   171  // QueryTransaction query transaction
   172  func (c *Turingchain) QueryTransaction(in rpctypes.QueryParm, result *interface{}) error {
   173  	var data types.ReqHash
   174  	hash, err := common.FromHex(in.Hash)
   175  	if err != nil {
   176  		return err
   177  	}
   178  
   179  	data.Hash = hash
   180  	reply, err := c.cli.QueryTx(&data)
   181  	if err != nil {
   182  		return err
   183  	}
   184  
   185  	transDetail, err := fmtTxDetail(reply, false)
   186  	if err != nil {
   187  		return err
   188  	}
   189  
   190  	*result = transDetail
   191  
   192  	return nil
   193  }
   194  
   195  // GetBlocks get block information
   196  func (c *Turingchain) GetBlocks(in rpctypes.BlockParam, result *interface{}) error {
   197  	reply, err := c.cli.GetBlocks(&types.ReqBlocks{Start: in.Start, End: in.End, IsDetail: in.Isdetail, Pid: []string{""}})
   198  	if err != nil {
   199  		return err
   200  	}
   201  	{
   202  		var blockDetails rpctypes.BlockDetails
   203  		items := reply.GetItems()
   204  		if err := convertBlockDetails(items, &blockDetails, in.Isdetail); err != nil {
   205  			return err
   206  		}
   207  		*result = &blockDetails
   208  	}
   209  
   210  	return nil
   211  
   212  }
   213  
   214  // GetLastHeader get last header
   215  func (c *Turingchain) GetLastHeader(in *types.ReqNil, result *interface{}) error {
   216  	reply, err := c.cli.GetLastHeader()
   217  	if err != nil {
   218  		return err
   219  	}
   220  
   221  	{
   222  		var header rpctypes.Header
   223  		header.BlockTime = reply.GetBlockTime()
   224  		header.Height = reply.GetHeight()
   225  		header.ParentHash = common.ToHex(reply.GetParentHash())
   226  		header.StateHash = common.ToHex(reply.GetStateHash())
   227  		header.TxHash = common.ToHex(reply.GetTxHash())
   228  		header.Version = reply.GetVersion()
   229  		header.Hash = common.ToHex(reply.GetHash())
   230  		header.TxCount = reply.TxCount
   231  		header.Difficulty = reply.GetDifficulty()
   232  		/* 空值,斩不显示
   233  		Signature: &Signature{
   234  			Ty:        reply.GetSignature().GetTy(),
   235  			Pubkey:    common.ToHex(reply.GetSignature().GetPubkey()),
   236  			Signature: common.ToHex(reply.GetSignature().GetSignature()),
   237  		}
   238  		*/
   239  		*result = &header
   240  	}
   241  
   242  	return nil
   243  }
   244  
   245  // GetTxByAddr get transaction by address
   246  // GetTxByAddr(parm *types.ReqAddr) (*types.ReplyTxInfo, error)
   247  func (c *Turingchain) GetTxByAddr(in types.ReqAddr, result *interface{}) error {
   248  	reply, err := c.cli.GetTransactionByAddr(&in)
   249  	if err != nil {
   250  		return err
   251  	}
   252  	{
   253  		var txinfos rpctypes.ReplyTxInfos
   254  		infos := reply.GetTxInfos()
   255  		for _, info := range infos {
   256  			txinfos.TxInfos = append(txinfos.TxInfos, &rpctypes.ReplyTxInfo{Hash: common.ToHex(info.GetHash()),
   257  				Height: info.GetHeight(), Index: info.GetIndex(), Assets: fmtAsssets(info.Assets)})
   258  		}
   259  		*result = &txinfos
   260  	}
   261  
   262  	return nil
   263  }
   264  
   265  // GetTxByHashes get transaction by hashes
   266  /*
   267  GetTxByHashes(parm *types.ReqHashes) (*types.TransactionDetails, error)
   268  GetMempool() (*types.ReplyTxList, error)
   269  GetAccounts() (*types.WalletAccounts, error)
   270  */
   271  func (c *Turingchain) GetTxByHashes(in rpctypes.ReqHashes, result *interface{}) error {
   272  	log.Warn("GetTxByHashes", "hashes", in)
   273  	var parm types.ReqHashes
   274  	parm.Hashes = make([][]byte, 0)
   275  	for _, v := range in.Hashes {
   276  		//hb := common.FromHex(v)
   277  		hb, err := common.FromHex(v)
   278  		if err != nil {
   279  			parm.Hashes = append(parm.Hashes, nil)
   280  			continue
   281  		}
   282  		parm.Hashes = append(parm.Hashes, hb)
   283  
   284  	}
   285  	reply, err := c.cli.GetTransactionByHash(&parm)
   286  	if err != nil {
   287  		return err
   288  	}
   289  	txs := reply.GetTxs()
   290  	log.Info("GetTxByHashes", "get tx with count", len(txs))
   291  	var txdetails rpctypes.TransactionDetails
   292  	if 0 != len(txs) {
   293  		for _, tx := range txs {
   294  			txDetail, err := fmtTxDetail(tx, in.DisableDetail)
   295  			if err != nil {
   296  				return err
   297  			}
   298  			txdetails.Txs = append(txdetails.Txs, txDetail)
   299  		}
   300  	}
   301  	*result = &txdetails
   302  	return nil
   303  }
   304  
   305  func fmtTxDetail(tx *types.TransactionDetail, disableDetail bool) (*rpctypes.TransactionDetail, error) {
   306  	//增加判断,上游接口可能返回空指针
   307  	if tx == nil || tx.GetTx() == nil {
   308  		//参数中hash和返回的detail一一对应,顺序一致
   309  		return nil, nil
   310  	}
   311  
   312  	var recp rpctypes.ReceiptData
   313  	recp.Ty = tx.GetReceipt().GetTy()
   314  	logs := tx.GetReceipt().GetLogs()
   315  	if disableDetail {
   316  		logs = nil
   317  	}
   318  	for _, lg := range logs {
   319  		recp.Logs = append(recp.Logs,
   320  			&rpctypes.ReceiptLog{Ty: lg.Ty, Log: common.ToHex(lg.GetLog())})
   321  	}
   322  
   323  	var recpResult *rpctypes.ReceiptDataResult
   324  	recpResult, err := rpctypes.DecodeLog(tx.Tx.Execer, &recp)
   325  	if err != nil {
   326  		log.Error("GetTxByHashes", "Failed to DecodeLog for type", err)
   327  		return nil, err
   328  	}
   329  
   330  	var proofs []string
   331  	txProofs := tx.GetProofs()
   332  	for _, proof := range txProofs {
   333  		proofs = append(proofs, common.ToHex(proof))
   334  	}
   335  
   336  	tran, err := rpctypes.DecodeTx(tx.GetTx())
   337  	if err != nil {
   338  		log.Info("GetTxByHashes", "Failed to DecodeTx due to", err)
   339  		return nil, err
   340  	}
   341  	//对Amount做格式化
   342  	if tx.Amount != 0 {
   343  		tran.Amount = tx.Amount
   344  		tran.AmountFmt = strconv.FormatFloat(float64(tran.Amount)/float64(types.Coin), 'f', 4, 64)
   345  	}
   346  	// swap from with to
   347  	if tx.GetTx().IsWithdraw() {
   348  		tx.Fromaddr, tx.Tx.To = tx.Tx.To, tx.Fromaddr
   349  		tran.To = tx.Tx.GetRealToAddr()
   350  	}
   351  	//交易fullhash
   352  	var fullhash string
   353  	if len(tx.GetFullHash()) != 0 {
   354  		fullhash = common.ToHex(tx.GetFullHash())
   355  	}
   356  	return &rpctypes.TransactionDetail{
   357  		Tx:         tran,
   358  		Height:     tx.GetHeight(),
   359  		Index:      tx.GetIndex(),
   360  		Blocktime:  tx.GetBlocktime(),
   361  		Receipt:    recpResult,
   362  		Proofs:     proofs,
   363  		Amount:     tx.GetAmount(),
   364  		Fromaddr:   tx.GetFromaddr(),
   365  		ActionName: tx.GetActionName(),
   366  		Assets:     fmtAsssets(tx.GetAssets()),
   367  		TxProofs:   fmtTxProofs(tx.GetTxProofs()),
   368  		FullHash:   fullhash,
   369  	}, nil
   370  }
   371  
   372  func fmtAsssets(assets []*types.Asset) []*rpctypes.Asset {
   373  	var result []*rpctypes.Asset
   374  	for _, a := range assets {
   375  		asset := &rpctypes.Asset{
   376  			Exec:   a.Exec,
   377  			Symbol: a.Symbol,
   378  			Amount: a.Amount,
   379  		}
   380  		result = append(result, asset)
   381  	}
   382  	return result
   383  }
   384  
   385  // GetMempool get mempool information
   386  func (c *Turingchain) GetMempool(in *types.ReqGetMempool, result *interface{}) error {
   387  	reply, err := c.cli.GetMempool(in)
   388  	if err != nil {
   389  		return err
   390  	}
   391  	{
   392  		var txlist rpctypes.ReplyTxList
   393  		txs := reply.GetTxs()
   394  		for _, tx := range txs {
   395  			amount, err := tx.Amount()
   396  			if err != nil {
   397  				amount = 0
   398  			}
   399  			tran, err := rpctypes.DecodeTx(tx)
   400  			if err != nil {
   401  				continue
   402  			}
   403  			tran.Amount = amount
   404  			txlist.Txs = append(txlist.Txs, tran)
   405  		}
   406  		*result = &txlist
   407  	}
   408  
   409  	return nil
   410  }
   411  
   412  // GetAccountsV2 get accounts for version 2
   413  func (c *Turingchain) GetAccountsV2(in *types.ReqNil, result *interface{}) error {
   414  	req := &types.ReqAccountList{WithoutBalance: false}
   415  	return c.GetAccounts(req, result)
   416  }
   417  
   418  // GetAccounts get accounts
   419  func (c *Turingchain) GetAccounts(in *types.ReqAccountList, result *interface{}) error {
   420  	req := types.ReqAccountList{WithoutBalance: in.WithoutBalance}
   421  	reply, err := c.cli.ExecWalletFunc("wallet", "WalletGetAccountList", &req)
   422  	if err != nil {
   423  		return err
   424  	}
   425  
   426  	accountsList := reply.(*types.WalletAccounts)
   427  	var accounts rpctypes.WalletAccounts
   428  	for _, wallet := range accountsList.Wallets {
   429  		accounts.Wallets = append(accounts.Wallets, &rpctypes.WalletAccount{Label: wallet.GetLabel(),
   430  			Acc: &rpctypes.Account{Currency: wallet.GetAcc().GetCurrency(), Balance: wallet.GetAcc().GetBalance(),
   431  				Frozen: wallet.GetAcc().GetFrozen(), Addr: wallet.GetAcc().GetAddr()}})
   432  	}
   433  
   434  	*result = &accounts
   435  	return nil
   436  }
   437  
   438  // NewAccount new a account
   439  func (c *Turingchain) NewAccount(in types.ReqNewAccount, result *interface{}) error {
   440  	reply, err := c.cli.ExecWalletFunc("wallet", "NewAccount", &in)
   441  	if err != nil {
   442  		return err
   443  	}
   444  
   445  	*result = reply
   446  	return nil
   447  }
   448  
   449  // WalletTxList transaction list of wallet
   450  func (c *Turingchain) WalletTxList(in rpctypes.ReqWalletTransactionList, result *interface{}) error {
   451  	var parm types.ReqWalletTransactionList
   452  	parm.FromTx = []byte(in.FromTx)
   453  	parm.Count = in.Count
   454  	parm.Direction = in.Direction
   455  	reply, err := c.cli.ExecWalletFunc("wallet", "WalletTransactionList", &parm)
   456  	if err != nil {
   457  		return err
   458  	}
   459  	{
   460  		var txdetails rpctypes.WalletTxDetails
   461  		err := rpctypes.ConvertWalletTxDetailToJSON(reply.(*types.WalletTxDetails), &txdetails)
   462  		if err != nil {
   463  			return err
   464  		}
   465  		*result = &txdetails
   466  	}
   467  	return nil
   468  }
   469  
   470  // ImportPrivkey import privkey of wallet
   471  func (c *Turingchain) ImportPrivkey(in types.ReqWalletImportPrivkey, result *interface{}) error {
   472  	reply, err := c.cli.ExecWalletFunc("wallet", "WalletImportPrivkey", &in)
   473  	if err != nil {
   474  		return err
   475  	}
   476  	*result = reply
   477  	return nil
   478  }
   479  
   480  // SendToAddress send to address of coins
   481  func (c *Turingchain) SendToAddress(in types.ReqWalletSendToAddress, result *interface{}) error {
   482  	reply, err := c.cli.ExecWalletFunc("wallet", "WalletSendToAddress", &in)
   483  	if err != nil {
   484  		log.Debug("SendToAddress", "Error", err.Error())
   485  		return err
   486  	}
   487  
   488  	log.Debug("sendtoaddr", "msg", reply.String())
   489  	*result = &rpctypes.ReplyHash{Hash: common.ToHex(reply.(*types.ReplyHash).GetHash())}
   490  	log.Debug("SendToAddress", "resulrt", *result)
   491  	return nil
   492  }
   493  
   494  // SetTxFee set tx fee
   495  func (c *Turingchain) SetTxFee(in types.ReqWalletSetFee, result *interface{}) error {
   496  	reply, err := c.cli.ExecWalletFunc("wallet", "WalletSetFee", &in)
   497  	if err != nil {
   498  		return err
   499  	}
   500  
   501  	var resp rpctypes.Reply
   502  	resp.IsOk = reply.(*types.Reply).GetIsOk()
   503  	resp.Msg = string(reply.(*types.Reply).GetMsg())
   504  	*result = &resp
   505  	return nil
   506  }
   507  
   508  // SetLabl set lable
   509  func (c *Turingchain) SetLabl(in types.ReqWalletSetLabel, result *interface{}) error {
   510  	reply, err := c.cli.ExecWalletFunc("wallet", "WalletSetLabel", &in)
   511  	if err != nil {
   512  		return err
   513  	}
   514  
   515  	*result = &rpctypes.WalletAccount{Acc: &rpctypes.Account{Addr: reply.(*types.WalletAccount).GetAcc().Addr, Currency: reply.(*types.WalletAccount).GetAcc().GetCurrency(),
   516  		Frozen: reply.(*types.WalletAccount).GetAcc().GetFrozen(), Balance: reply.(*types.WalletAccount).GetAcc().GetBalance()}, Label: reply.(*types.WalletAccount).GetLabel()}
   517  	return nil
   518  }
   519  
   520  //GetAccount getAddress by lable
   521  func (c *Turingchain) GetAccount(in types.ReqGetAccount, result *interface{}) error {
   522  	reply, err := c.cli.ExecWalletFunc("wallet", "WalletGetAccount", &in)
   523  	if err != nil {
   524  		return err
   525  	}
   526  
   527  	*result = &rpctypes.WalletAccount{Acc: &rpctypes.Account{Addr: reply.(*types.WalletAccount).GetAcc().Addr, Currency: reply.(*types.WalletAccount).GetAcc().GetCurrency(),
   528  		Frozen: reply.(*types.WalletAccount).GetAcc().GetFrozen(), Balance: reply.(*types.WalletAccount).GetAcc().GetBalance()}, Label: reply.(*types.WalletAccount).GetLabel()}
   529  	return nil
   530  
   531  }
   532  
   533  // MergeBalance merge balance
   534  func (c *Turingchain) MergeBalance(in types.ReqWalletMergeBalance, result *interface{}) error {
   535  	reply, err := c.cli.ExecWalletFunc("wallet", "WalletMergeBalance", &in)
   536  	if err != nil {
   537  		return err
   538  	}
   539  
   540  	var hashes rpctypes.ReplyHashes
   541  	for _, has := range reply.(*types.ReplyHashes).Hashes {
   542  		hashes.Hashes = append(hashes.Hashes, common.ToHex(has))
   543  	}
   544  	*result = &hashes
   545  	return nil
   546  }
   547  
   548  // SetPasswd set password
   549  func (c *Turingchain) SetPasswd(in types.ReqWalletSetPasswd, result *interface{}) error {
   550  	reply, err := c.cli.ExecWalletFunc("wallet", "WalletSetPasswd", &in)
   551  	if err != nil {
   552  		return err
   553  	}
   554  
   555  	var resp rpctypes.Reply
   556  	resp.IsOk = reply.(*types.Reply).GetIsOk()
   557  	resp.Msg = string(reply.(*types.Reply).GetMsg())
   558  	*result = &resp
   559  	return nil
   560  }
   561  
   562  // Lock wallet lock
   563  func (c *Turingchain) Lock(in types.ReqNil, result *interface{}) error {
   564  	reply, err := c.cli.ExecWalletFunc("wallet", "WalletLock", &in)
   565  	if err != nil {
   566  		return err
   567  	}
   568  
   569  	var resp rpctypes.Reply
   570  	resp.IsOk = reply.(*types.Reply).GetIsOk()
   571  	resp.Msg = string(reply.(*types.Reply).GetMsg())
   572  	*result = &resp
   573  	return nil
   574  }
   575  
   576  // UnLock wallet unlock
   577  func (c *Turingchain) UnLock(in types.WalletUnLock, result *interface{}) error {
   578  	reply, err := c.cli.ExecWalletFunc("wallet", "WalletUnLock", &in)
   579  	if err != nil {
   580  		return err
   581  	}
   582  
   583  	var resp rpctypes.Reply
   584  	resp.IsOk = reply.(*types.Reply).GetIsOk()
   585  	resp.Msg = string(reply.(*types.Reply).GetMsg())
   586  	*result = &resp
   587  	return nil
   588  }
   589  
   590  // GetPeerInfo get peer information
   591  func (c *Turingchain) GetPeerInfo(in types.P2PGetPeerReq, result *interface{}) error {
   592  	reply, err := c.cli.PeerInfo(&in)
   593  	if err != nil {
   594  		return err
   595  	}
   596  	{
   597  
   598  		var peerlist rpctypes.PeerList
   599  		for _, peer := range reply.Peers {
   600  			var pr rpctypes.Peer
   601  			pr.Addr = peer.GetAddr()
   602  			pr.MempoolSize = peer.GetMempoolSize()
   603  			pr.Name = peer.GetName()
   604  			pr.Port = peer.GetPort()
   605  			pr.Self = peer.GetSelf()
   606  			pr.Header = &rpctypes.Header{
   607  				BlockTime:  peer.Header.GetBlockTime(),
   608  				Height:     peer.Header.GetHeight(),
   609  				ParentHash: common.ToHex(peer.GetHeader().GetParentHash()),
   610  				StateHash:  common.ToHex(peer.GetHeader().GetStateHash()),
   611  				TxHash:     common.ToHex(peer.GetHeader().GetTxHash()),
   612  				Version:    peer.GetHeader().GetVersion(),
   613  				Hash:       common.ToHex(peer.GetHeader().GetHash()),
   614  				TxCount:    peer.GetHeader().GetTxCount(),
   615  			}
   616  
   617  			pr.Version = peer.GetVersion()
   618  			pr.LocalDBVersion = peer.GetLocalDBVersion()
   619  			pr.StoreDBVersion = peer.GetStoreDBVersion()
   620  			peerlist.Peers = append(peerlist.Peers, &pr)
   621  
   622  		}
   623  		*result = &peerlist
   624  	}
   625  
   626  	return nil
   627  }
   628  
   629  // GetHeaders get headers
   630  func (c *Turingchain) GetHeaders(in types.ReqBlocks, result *interface{}) error {
   631  	reply, err := c.cli.GetHeaders(&in)
   632  	if err != nil {
   633  		return err
   634  	}
   635  	var headers rpctypes.Headers
   636  	{
   637  		for _, item := range reply.Items {
   638  			headers.Items = append(headers.Items, &rpctypes.Header{
   639  				BlockTime:  item.GetBlockTime(),
   640  				TxCount:    item.GetTxCount(),
   641  				Hash:       common.ToHex(item.GetHash()),
   642  				Height:     item.GetHeight(),
   643  				ParentHash: common.ToHex(item.GetParentHash()),
   644  				StateHash:  common.ToHex(item.GetStateHash()),
   645  				TxHash:     common.ToHex(item.GetTxHash()),
   646  				Difficulty: item.GetDifficulty(),
   647  				/* 空值,斩不显示
   648  				Signature: &Signature{
   649  					Ty:        item.GetSignature().GetTy(),
   650  					Pubkey:    common.ToHex(item.GetSignature().GetPubkey()),
   651  					Signature: common.ToHex(item.GetSignature().GetSignature()),
   652  				},
   653  				*/
   654  				Version: item.GetVersion()})
   655  		}
   656  		*result = &headers
   657  	}
   658  	return nil
   659  }
   660  
   661  // GetLastMemPool get  contents in last mempool
   662  func (c *Turingchain) GetLastMemPool(in types.ReqNil, result *interface{}) error {
   663  	reply, err := c.cli.GetLastMempool()
   664  	if err != nil {
   665  		return err
   666  	}
   667  
   668  	{
   669  		var txlist rpctypes.ReplyTxList
   670  		txs := reply.GetTxs()
   671  		for _, tx := range txs {
   672  			tran, err := rpctypes.DecodeTx(tx)
   673  			if err != nil {
   674  				continue
   675  			}
   676  			txlist.Txs = append(txlist.Txs, tran)
   677  		}
   678  		*result = &txlist
   679  	}
   680  	return nil
   681  }
   682  
   683  // GetProperFee get  contents in proper fee
   684  func (c *Turingchain) GetProperFee(in types.ReqProperFee, result *interface{}) error {
   685  	reply, err := c.cli.GetProperFee(&in)
   686  	if err != nil {
   687  		return err
   688  	}
   689  	var properFee rpctypes.ReplyProperFee
   690  	properFee.ProperFee = reply.GetProperFee()
   691  	*result = &properFee
   692  	return nil
   693  }
   694  
   695  // GetBlockOverview get overview of block
   696  // GetBlockOverview(parm *types.ReqHash) (*types.BlockOverview, error)
   697  func (c *Turingchain) GetBlockOverview(in rpctypes.QueryParm, result *interface{}) error {
   698  	var data types.ReqHash
   699  	hash, err := common.FromHex(in.Hash)
   700  	if err != nil {
   701  		return err
   702  	}
   703  
   704  	data.Hash = hash
   705  	reply, err := c.cli.GetBlockOverview(&data)
   706  	if err != nil {
   707  		return err
   708  	}
   709  	var blockOverview rpctypes.BlockOverview
   710  
   711  	//获取blockheader信息
   712  	var header rpctypes.Header
   713  	header.BlockTime = reply.GetHead().GetBlockTime()
   714  	header.Height = reply.GetHead().GetHeight()
   715  	header.ParentHash = common.ToHex(reply.GetHead().GetParentHash())
   716  	header.StateHash = common.ToHex(reply.GetHead().GetStateHash())
   717  	header.TxHash = common.ToHex(reply.GetHead().GetTxHash())
   718  	header.Version = reply.GetHead().GetVersion()
   719  	header.Hash = common.ToHex(reply.GetHead().GetHash())
   720  	header.TxCount = reply.GetHead().GetTxCount()
   721  	header.Difficulty = reply.GetHead().GetDifficulty()
   722  	/* 空值,斩不显示
   723  	header.Signature = &Signature{
   724  		Ty:        reply.GetHead().GetSignature().GetTy(),
   725  		Pubkey:    common.ToHex(reply.GetHead().GetSignature().GetPubkey()),
   726  		Signature: common.ToHex(reply.GetHead().GetSignature().GetSignature()),
   727  	}
   728  	*/
   729  	blockOverview.Head = &header
   730  
   731  	//获取blocktxhashs信息
   732  	for _, has := range reply.GetTxHashes() {
   733  		blockOverview.TxHashes = append(blockOverview.TxHashes, common.ToHex(has))
   734  	}
   735  
   736  	blockOverview.TxCount = reply.GetTxCount()
   737  	*result = &blockOverview
   738  	return nil
   739  }
   740  
   741  // GetAddrOverview get overview of address
   742  func (c *Turingchain) GetAddrOverview(in types.ReqAddr, result *interface{}) error {
   743  	reply, err := c.cli.GetAddrOverview(&in)
   744  	if err != nil {
   745  		return err
   746  	}
   747  	*result = reply
   748  	return nil
   749  }
   750  
   751  // GetBlockHash get block hash
   752  func (c *Turingchain) GetBlockHash(in types.ReqInt, result *interface{}) error {
   753  	reply, err := c.cli.GetBlockHash(&in)
   754  	if err != nil {
   755  		return err
   756  	}
   757  	var replyHash rpctypes.ReplyHash
   758  	replyHash.Hash = common.ToHex(reply.GetHash())
   759  	*result = &replyHash
   760  	return nil
   761  }
   762  
   763  // GenSeed seed
   764  func (c *Turingchain) GenSeed(in types.GenSeedLang, result *interface{}) error {
   765  	reply, err := c.cli.ExecWalletFunc("wallet", "GenSeed", &in)
   766  	if err != nil {
   767  		return err
   768  	}
   769  	*result = reply
   770  	return nil
   771  }
   772  
   773  // SaveSeed save seed
   774  func (c *Turingchain) SaveSeed(in types.SaveSeedByPw, result *interface{}) error {
   775  	reply, err := c.cli.ExecWalletFunc("wallet", "SaveSeed", &in)
   776  	if err != nil {
   777  		return err
   778  	}
   779  
   780  	var resp rpctypes.Reply
   781  	resp.IsOk = reply.(*types.Reply).GetIsOk()
   782  	resp.Msg = string(reply.(*types.Reply).GetMsg())
   783  	*result = &resp
   784  	return nil
   785  }
   786  
   787  // GetSeed get seed
   788  func (c *Turingchain) GetSeed(in types.GetSeedByPw, result *interface{}) error {
   789  	reply, err := c.cli.ExecWalletFunc("wallet", "GetSeed", &in)
   790  	if err != nil {
   791  		return err
   792  	}
   793  	*result = reply
   794  	return nil
   795  }
   796  
   797  // GetWalletStatus get status of wallet
   798  func (c *Turingchain) GetWalletStatus(in types.ReqNil, result *interface{}) error {
   799  	reply, err := c.cli.ExecWalletFunc("wallet", "GetWalletStatus", &in)
   800  	if err != nil {
   801  		return err
   802  	}
   803  
   804  	status := rpctypes.WalletStatus{
   805  		IsWalletLock: reply.(*types.WalletStatus).IsWalletLock,
   806  		IsAutoMining: reply.(*types.WalletStatus).IsAutoMining,
   807  		IsHasSeed:    reply.(*types.WalletStatus).IsHasSeed,
   808  		IsTicketLock: reply.(*types.WalletStatus).IsTicketLock,
   809  	}
   810  	*result = &status
   811  	return nil
   812  }
   813  
   814  // GetBalance get balance
   815  func (c *Turingchain) GetBalance(in types.ReqBalance, result *interface{}) error {
   816  	//增加addr地址的校验
   817  	for _, addr := range in.GetAddresses() {
   818  		err := address.CheckAddress(addr)
   819  		if err != nil {
   820  			if err = address.CheckMultiSignAddress(addr); err != nil {
   821  				return types.ErrInvalidAddress
   822  			}
   823  		}
   824  	}
   825  	balances, err := c.cli.GetBalance(&in)
   826  	if err != nil {
   827  		return err
   828  	}
   829  
   830  	*result = fmtAccount(balances)
   831  	return nil
   832  }
   833  
   834  // GetAllExecBalance get all balance of exec
   835  func (c *Turingchain) GetAllExecBalance(in types.ReqAllExecBalance, result *interface{}) error {
   836  	balance, err := c.cli.GetAllExecBalance(&in)
   837  	if err != nil {
   838  		return err
   839  	}
   840  
   841  	allBalance := &rpctypes.AllExecBalance{Addr: in.Addr}
   842  	for _, execAcc := range balance.ExecAccount {
   843  		res := &rpctypes.ExecAccount{Execer: execAcc.Execer}
   844  		acc := &rpctypes.Account{
   845  			Balance:  execAcc.Account.GetBalance(),
   846  			Currency: execAcc.Account.GetCurrency(),
   847  			Frozen:   execAcc.Account.GetFrozen(),
   848  		}
   849  		res.Account = acc
   850  		allBalance.ExecAccount = append(allBalance.ExecAccount, res)
   851  	}
   852  	*result = allBalance
   853  	return nil
   854  }
   855  
   856  // ExecWallet exec wallet
   857  func (c *Turingchain) ExecWallet(in *rpctypes.ChainExecutor, result *interface{}) error {
   858  	hash, err := common.FromHex(in.StateHash)
   859  	if err != nil {
   860  		return err
   861  	}
   862  	param, err := wcom.QueryData.DecodeJSON(in.Driver, in.FuncName, in.Payload)
   863  	if err != nil {
   864  		return err
   865  	}
   866  	execdata := &types.ChainExecutor{
   867  		Driver:    in.Driver,
   868  		FuncName:  in.FuncName,
   869  		StateHash: hash,
   870  		Param:     types.Encode(param),
   871  	}
   872  	msg, err := c.cli.ExecWallet(execdata)
   873  	if err != nil {
   874  		return err
   875  	}
   876  	var jsonmsg json.RawMessage
   877  	jsonmsg, err = types.PBToJSON(msg)
   878  	if err != nil {
   879  		return err
   880  	}
   881  	*result = jsonmsg
   882  	return nil
   883  }
   884  
   885  // Query query
   886  func (c *Turingchain) Query(in rpctypes.Query4Jrpc, result *interface{}) error {
   887  	cfg := c.cli.GetConfig()
   888  	execty := types.LoadExecutorType(in.Execer)
   889  	if execty == nil {
   890  		log.Error("Query", "funcname", in.FuncName, "err", types.ErrNotSupport)
   891  		return types.ErrNotSupport
   892  	}
   893  	decodePayload, err := execty.CreateQuery(in.FuncName, in.Payload)
   894  	if err != nil {
   895  		log.Error("EventQuery1", "err", err.Error(), "funcName", in.FuncName)
   896  		return err
   897  	}
   898  	resp, err := c.cli.Query(cfg.ExecName(in.Execer), in.FuncName, decodePayload)
   899  	if err != nil {
   900  		log.Error("EventQuery2", "err", err.Error())
   901  		return err
   902  	}
   903  	var jsonmsg json.RawMessage
   904  	jsonmsg, err = execty.QueryToJSON(in.FuncName, resp)
   905  	*result = jsonmsg
   906  	if err != nil {
   907  		log.Error("EventQuery3", "err", err.Error())
   908  		return err
   909  	}
   910  	return nil
   911  }
   912  
   913  // DumpPrivkey dump privkey
   914  func (c *Turingchain) DumpPrivkey(in types.ReqString, result *interface{}) error {
   915  	reply, err := c.cli.ExecWalletFunc("wallet", "DumpPrivkey", &in)
   916  	if err != nil {
   917  		return err
   918  	}
   919  	*result = reply
   920  	return nil
   921  }
   922  
   923  // DumpPrivkeysFile dumps private key to file.
   924  func (c *Turingchain) DumpPrivkeysFile(in types.ReqPrivkeysFile, result *interface{}) error {
   925  	reply, err := c.cli.ExecWalletFunc("wallet", "DumpPrivkeysFile", &in)
   926  	if err != nil {
   927  		return err
   928  	}
   929  
   930  	var resp rpctypes.Reply
   931  	resp.IsOk = reply.(*types.Reply).GetIsOk()
   932  	resp.Msg = string(reply.(*types.Reply).GetMsg())
   933  	*result = &resp
   934  	return nil
   935  }
   936  
   937  // ImportPrivkeysFile imports private key from file.
   938  func (c *Turingchain) ImportPrivkeysFile(in types.ReqPrivkeysFile, result *interface{}) error {
   939  	reply, err := c.cli.ExecWalletFunc("wallet", "ImportPrivkeysFile", &in)
   940  	if err != nil {
   941  		return err
   942  	}
   943  
   944  	var resp rpctypes.Reply
   945  	resp.IsOk = reply.(*types.Reply).GetIsOk()
   946  	resp.Msg = string(reply.(*types.Reply).GetMsg())
   947  	*result = &resp
   948  	return nil
   949  }
   950  
   951  // Version get software version
   952  func (c *Turingchain) Version(in *types.ReqNil, result *interface{}) error {
   953  	resp, err := c.cli.Version()
   954  	if err != nil {
   955  		return err
   956  	}
   957  	*result = resp
   958  	return nil
   959  }
   960  
   961  // GetTotalCoins get total coins
   962  func (c *Turingchain) GetTotalCoins(in *types.ReqGetTotalCoins, result *interface{}) error {
   963  	resp, err := c.cli.GetTotalCoins(in)
   964  	if err != nil {
   965  		return err
   966  	}
   967  	*result = resp
   968  	return nil
   969  }
   970  
   971  // IsSync is sync or not
   972  func (c *Turingchain) IsSync(in *types.ReqNil, result *interface{}) error {
   973  	reply, err := c.cli.IsSync()
   974  	if err != nil {
   975  		return err
   976  	}
   977  	ret := false
   978  	if reply != nil {
   979  		ret = reply.IsOk
   980  	}
   981  	*result = ret
   982  	return nil
   983  }
   984  
   985  // IsNtpClockSync  is ntp clock sync
   986  func (c *Turingchain) IsNtpClockSync(in *types.ReqNil, result *interface{}) error {
   987  	reply, err := c.cli.IsNtpClockSync()
   988  	if err != nil {
   989  		return err
   990  	}
   991  	ret := false
   992  	if reply != nil {
   993  		ret = reply.IsOk
   994  	}
   995  	*result = ret
   996  	return nil
   997  }
   998  
   999  // QueryTotalFee query total fee
  1000  func (c *Turingchain) QueryTotalFee(in *types.LocalDBGet, result *interface{}) error {
  1001  	if in == nil || len(in.Keys) != 1 {
  1002  		return types.ErrInvalidParam
  1003  	}
  1004  	totalFeePrefix := []byte("TotalFeeKey:")
  1005  	//add prefix if not exist
  1006  	if !bytes.HasPrefix(in.Keys[0], totalFeePrefix) {
  1007  		in.Keys[0] = append(totalFeePrefix, in.Keys[0]...)
  1008  	}
  1009  	reply, err := c.cli.LocalGet(in)
  1010  	if err != nil {
  1011  		return err
  1012  	}
  1013  
  1014  	var fee types.TotalFee
  1015  	err = types.Decode(reply.Values[0], &fee)
  1016  	if err != nil {
  1017  		return err
  1018  	}
  1019  	*result = fee
  1020  	return nil
  1021  }
  1022  
  1023  // SignRawTx signature the rawtransaction
  1024  func (c *Turingchain) SignRawTx(in *types.ReqSignRawTx, result *interface{}) error {
  1025  	req := types.ReqSignRawTx{Addr: in.Addr, Privkey: in.Privkey, TxHex: in.TxHex, Expire: in.Expire,
  1026  		Index: in.Index, Token: in.Token, Fee: in.Fee, NewToAddr: in.NewToAddr}
  1027  	reply, err := c.cli.ExecWalletFunc("wallet", "SignRawTx", &req)
  1028  	if err != nil {
  1029  		return err
  1030  	}
  1031  	*result = reply.(*types.ReplySignRawTx).TxHex
  1032  	return nil
  1033  }
  1034  
  1035  // GetNetInfo get net information
  1036  func (c *Turingchain) GetNetInfo(in types.P2PGetNetInfoReq, result *interface{}) error {
  1037  	resp, err := c.cli.GetNetInfo(&in)
  1038  	if err != nil {
  1039  		return err
  1040  	}
  1041  	*result = &rpctypes.NodeNetinfo{
  1042  		Externaladdr: resp.GetExternaladdr(),
  1043  		Localaddr:    resp.GetLocaladdr(),
  1044  		Service:      resp.GetService(),
  1045  		Outbounds:    resp.GetOutbounds(),
  1046  		Inbounds:     resp.GetInbounds(),
  1047  		Peerstore:    resp.GetPeerstore(),
  1048  		Routingtable: resp.GetRoutingtable(),
  1049  		Ratein:       resp.GetRatein(),
  1050  		Rateout:      resp.GetRateout(),
  1051  		Ratetotal:    resp.GetRatetotal(),
  1052  	}
  1053  	return nil
  1054  }
  1055  
  1056  // GetFatalFailure return fatal failure
  1057  func (c *Turingchain) GetFatalFailure(in *types.ReqNil, result *interface{}) error {
  1058  	reply, err := c.cli.ExecWalletFunc("wallet", "FatalFailure", &types.ReqNil{})
  1059  	if err != nil {
  1060  		return err
  1061  	}
  1062  	*result = reply.(*types.Int32).Data
  1063  	return nil
  1064  }
  1065  
  1066  // DecodeRawTransaction 考虑交易组的解析统一返回ReplyTxList列表
  1067  func (c *Turingchain) DecodeRawTransaction(in *types.ReqDecodeRawTransaction, result *interface{}) error {
  1068  	tx, err := c.cli.DecodeRawTransaction(in)
  1069  	if err != nil {
  1070  		return err
  1071  	}
  1072  	txs, err := tx.GetTxGroup()
  1073  	if err != nil {
  1074  		return err
  1075  	}
  1076  	var rpctxs rpctypes.ReplyTxList
  1077  	if txs == nil {
  1078  		res, err := rpctypes.DecodeTx(tx)
  1079  		if err != nil {
  1080  			return err
  1081  		}
  1082  		rpctxs.Txs = append(rpctxs.Txs, res)
  1083  	} else {
  1084  		for _, rpctx := range txs.GetTxs() {
  1085  			res, err := rpctypes.DecodeTx(rpctx)
  1086  			if err != nil {
  1087  				return err
  1088  			}
  1089  			rpctxs.Txs = append(rpctxs.Txs, res)
  1090  		}
  1091  	}
  1092  	*result = &rpctxs
  1093  	return nil
  1094  }
  1095  
  1096  // GetTimeStatus get status of time
  1097  func (c *Turingchain) GetTimeStatus(in *types.ReqNil, result *interface{}) error {
  1098  	reply, err := c.cli.GetTimeStatus()
  1099  	if err != nil {
  1100  		return err
  1101  	}
  1102  	timeStatus := &rpctypes.TimeStatus{
  1103  		NtpTime:   reply.NtpTime,
  1104  		LocalTime: reply.LocalTime,
  1105  		Diff:      reply.Diff,
  1106  	}
  1107  	*result = timeStatus
  1108  	return nil
  1109  }
  1110  
  1111  // GetServerTime get server time
  1112  func (c *Turingchain) GetServerTime(in *types.ReqNil, result *interface{}) error {
  1113  
  1114  	serverTime := &types.ServerTime{
  1115  		CurrentTimestamp: types.Now().Unix(),
  1116  	}
  1117  	*result = serverTime
  1118  	return nil
  1119  }
  1120  
  1121  // CloseQueue close queue
  1122  func (c *Turingchain) CloseQueue(in *types.ReqNil, result *interface{}) error {
  1123  	go func() {
  1124  		time.Sleep(time.Millisecond * 100)
  1125  		_, err := c.cli.CloseQueue()
  1126  		if err != nil {
  1127  			return
  1128  		}
  1129  	}()
  1130  
  1131  	*result = &types.Reply{IsOk: true}
  1132  	return nil
  1133  }
  1134  
  1135  // GetLastBlockSequence get sequence last block
  1136  func (c *Turingchain) GetLastBlockSequence(in *types.ReqNil, result *interface{}) error {
  1137  	resp, err := c.cli.GetLastBlockSequence()
  1138  	if err != nil {
  1139  		return err
  1140  	}
  1141  	*result = resp.GetData()
  1142  	return nil
  1143  }
  1144  
  1145  // GetBlockSequences get the block loading sequence number information for the specified interval
  1146  func (c *Turingchain) GetBlockSequences(in rpctypes.BlockParam, result *interface{}) error {
  1147  	resp, err := c.cli.GetBlockSequences(&types.ReqBlocks{Start: in.Start, End: in.End, IsDetail: in.Isdetail, Pid: []string{""}})
  1148  	if err != nil {
  1149  		return err
  1150  	}
  1151  	var BlkSeqs rpctypes.ReplyBlkSeqs
  1152  	items := resp.GetItems()
  1153  	for _, item := range items {
  1154  		BlkSeqs.BlkSeqInfos = append(BlkSeqs.BlkSeqInfos, &rpctypes.ReplyBlkSeq{Hash: common.ToHex(item.GetHash()),
  1155  			Type: item.GetType()})
  1156  	}
  1157  	*result = &BlkSeqs
  1158  	return nil
  1159  }
  1160  
  1161  // GetBlockByHashes get block information by hashes
  1162  func (c *Turingchain) GetBlockByHashes(in rpctypes.ReqHashes, result *interface{}) error {
  1163  	log.Warn("GetBlockByHashes", "hashes", in)
  1164  	var parm types.ReqHashes
  1165  	parm.Hashes = make([][]byte, 0)
  1166  	for _, v := range in.Hashes {
  1167  		hb, err := common.FromHex(v)
  1168  		if err != nil {
  1169  			parm.Hashes = append(parm.Hashes, nil)
  1170  			continue
  1171  		}
  1172  		parm.Hashes = append(parm.Hashes, hb)
  1173  
  1174  	}
  1175  	reply, err := c.cli.GetBlockByHashes(&parm)
  1176  	if err != nil {
  1177  		return err
  1178  	}
  1179  	{
  1180  		var blockDetails rpctypes.BlockDetails
  1181  		items := reply.Items
  1182  		if err := convertBlockDetails(items, &blockDetails, !in.DisableDetail); err != nil {
  1183  			return err
  1184  		}
  1185  		*result = &blockDetails
  1186  	}
  1187  	return nil
  1188  }
  1189  
  1190  // CreateTransaction create transaction
  1191  func (c *Turingchain) CreateTransaction(in *rpctypes.CreateTxIn, result *interface{}) error {
  1192  	if in == nil {
  1193  		return types.ErrInvalidParam
  1194  	}
  1195  	cfg := c.cli.GetConfig()
  1196  	btx, err := types.CallCreateTxJSON(cfg, cfg.ExecName(in.Execer), in.ActionName, in.Payload)
  1197  	if err != nil {
  1198  		return err
  1199  	}
  1200  	*result = common.ToHex(btx)
  1201  	return nil
  1202  }
  1203  
  1204  // ConvertExectoAddr convert exec to address
  1205  func (c *Turingchain) ConvertExectoAddr(in rpctypes.ExecNameParm, result *string) error {
  1206  	*result = address.ExecAddress(in.ExecName)
  1207  	return nil
  1208  }
  1209  
  1210  // GetExecBalance get balance exec
  1211  func (c *Turingchain) GetExecBalance(in *types.ReqGetExecBalance, result *interface{}) error {
  1212  	resp, err := c.cli.GetExecBalance(in)
  1213  	if err != nil {
  1214  		return err
  1215  	}
  1216  	//*result = resp
  1217  	*result = hex.EncodeToString(types.Encode(resp))
  1218  	return nil
  1219  }
  1220  
  1221  // AddPushSubscribe  add Seq CallBack
  1222  func (c *Turingchain) AddPushSubscribe(in *types.PushSubscribeReq, result *interface{}) error {
  1223  	resp, err := c.cli.AddPushSubscribe(in)
  1224  	log.Error("AddPushSubscribe", "err", err, "reply", resp)
  1225  
  1226  	if err != nil {
  1227  		return err
  1228  	}
  1229  	*result = resp
  1230  	return nil
  1231  }
  1232  
  1233  // ListPushes  List Seq CallBack
  1234  func (c *Turingchain) ListPushes(in *types.ReqNil, result *interface{}) error {
  1235  	resp, err := c.cli.ListPushes()
  1236  	if err != nil {
  1237  		return err
  1238  	}
  1239  	*result = resp
  1240  	return nil
  1241  }
  1242  
  1243  // GetPushSeqLastNum  Get Seq Call Back Last Num
  1244  func (c *Turingchain) GetPushSeqLastNum(in *types.ReqString, result *interface{}) error {
  1245  	resp, err := c.cli.GetPushSeqLastNum(in)
  1246  	if err != nil {
  1247  		return err
  1248  	}
  1249  	*result = resp
  1250  	return nil
  1251  }
  1252  
  1253  func convertBlockDetails(details []*types.BlockDetail, retDetails *rpctypes.BlockDetails, isDetail bool) error {
  1254  	for _, item := range details {
  1255  		var bdtl rpctypes.BlockDetail
  1256  		var block rpctypes.Block
  1257  		if item == nil || item.GetBlock() == nil {
  1258  			retDetails.Items = append(retDetails.Items, nil)
  1259  			continue
  1260  		}
  1261  		block.BlockTime = item.Block.GetBlockTime()
  1262  		block.Height = item.Block.GetHeight()
  1263  		block.Version = item.Block.GetVersion()
  1264  		block.ParentHash = common.ToHex(item.Block.GetParentHash())
  1265  		block.StateHash = common.ToHex(item.Block.GetStateHash())
  1266  		block.TxHash = common.ToHex(item.Block.GetTxHash())
  1267  		block.Difficulty = item.Block.Difficulty
  1268  		block.MainHash = common.ToHex(item.Block.MainHash)
  1269  		block.MainHeight = item.Block.MainHeight
  1270  		if item.Block.Signature != nil {
  1271  			block.Signature = &rpctypes.Signature{Ty: item.Block.Signature.Ty, Pubkey: common.ToHex(item.Block.Signature.Pubkey),
  1272  				Signature: common.ToHex(item.Block.Signature.Signature)}
  1273  		}
  1274  
  1275  		txs := item.Block.GetTxs()
  1276  		if isDetail && len(txs) != len(item.Receipts) { //只有获取详情时才需要校验txs和Receipts的数量是否相等TURINGCHAIN-540
  1277  			return types.ErrDecode
  1278  		}
  1279  		for _, tx := range txs {
  1280  			tran, err := rpctypes.DecodeTx(tx)
  1281  			if err != nil {
  1282  				continue
  1283  			}
  1284  			block.Txs = append(block.Txs, tran)
  1285  		}
  1286  		bdtl.Block = &block
  1287  
  1288  		for i, rp := range item.Receipts {
  1289  			var recp rpctypes.ReceiptData
  1290  			recp.Ty = rp.GetTy()
  1291  			for _, log := range rp.Logs {
  1292  				recp.Logs = append(recp.Logs,
  1293  					&rpctypes.ReceiptLog{Ty: log.Ty, Log: common.ToHex(log.GetLog())})
  1294  			}
  1295  			rd, err := rpctypes.DecodeLog(txs[i].Execer, &recp)
  1296  			if err != nil {
  1297  				continue
  1298  			}
  1299  			bdtl.Receipts = append(bdtl.Receipts, rd)
  1300  		}
  1301  
  1302  		retDetails.Items = append(retDetails.Items, &bdtl)
  1303  	}
  1304  	return nil
  1305  }
  1306  
  1307  func fmtAccount(balances []*types.Account) []*rpctypes.Account {
  1308  	var accounts []*rpctypes.Account
  1309  	for _, balance := range balances {
  1310  		accounts = append(accounts, &rpctypes.Account{Addr: balance.GetAddr(),
  1311  			Balance:  balance.GetBalance(),
  1312  			Currency: balance.GetCurrency(),
  1313  			Frozen:   balance.GetFrozen()})
  1314  	}
  1315  	return accounts
  1316  }
  1317  
  1318  // GetCoinSymbol get coin symbol
  1319  func (c *Turingchain) GetCoinSymbol(in types.ReqNil, result *interface{}) error {
  1320  	cfg := c.cli.GetConfig()
  1321  	symbol := cfg.GetCoinSymbol()
  1322  	resp := types.ReplyString{Data: symbol}
  1323  	log.Warn("GetCoinSymbol", "Symbol", symbol)
  1324  	*result = &resp
  1325  	return nil
  1326  }
  1327  
  1328  func fmtTxProofs(txProofs []*types.TxProof) []*rpctypes.TxProof {
  1329  	var result []*rpctypes.TxProof
  1330  	for _, txproof := range txProofs {
  1331  		var proofs []string
  1332  		for _, proof := range txproof.GetProofs() {
  1333  			proofs = append(proofs, common.ToHex(proof))
  1334  		}
  1335  		rpctxproof := &rpctypes.TxProof{
  1336  			Proofs:   proofs,
  1337  			Index:    txproof.GetIndex(),
  1338  			RootHash: common.ToHex(txproof.GetRootHash()),
  1339  		}
  1340  		result = append(result, rpctxproof)
  1341  	}
  1342  	return result
  1343  }
  1344  
  1345  // NetProtocols get net information
  1346  func (c *Turingchain) NetProtocols(in types.ReqNil, result *interface{}) error {
  1347  	resp, err := c.cli.NetProtocols(&in)
  1348  	if err != nil {
  1349  		return err
  1350  	}
  1351  
  1352  	*result = resp
  1353  	return nil
  1354  }
  1355  
  1356  //GetSequenceByHash get sequcen by hashes
  1357  func (c *Turingchain) GetSequenceByHash(in rpctypes.ReqHashes, result *interface{}) error {
  1358  	if len(in.Hashes) != 0 && common.IsHex(in.Hashes[0]) {
  1359  		var req types.ReqHash
  1360  		req.Upgrade = in.DisableDetail
  1361  		req.Hash = common.HexToHash(in.Hashes[0]).Bytes()
  1362  		seq, err := c.cli.GetSequenceByHash(&req)
  1363  		if err != nil {
  1364  			return err
  1365  		}
  1366  		*result = seq
  1367  		return nil
  1368  	}
  1369  
  1370  	return types.ErrInvalidParam
  1371  
  1372  }
  1373  
  1374  //GetBlockBySeq get block by seq
  1375  func (c *Turingchain) GetBlockBySeq(in types.Int64, result *interface{}) error {
  1376  
  1377  	blockSeq, err := c.cli.GetBlockBySeq(&in)
  1378  	if err != nil {
  1379  		return err
  1380  	}
  1381  	var bseq rpctypes.BlockSeq
  1382  	var retDetail rpctypes.BlockDetails
  1383  
  1384  	bseq.Num = blockSeq.Num
  1385  	err = convertBlockDetails([]*types.BlockDetail{blockSeq.Detail}, &retDetail, false)
  1386  	bseq.Detail = retDetail.Items[0]
  1387  	bseq.Seq = &rpctypes.BlockSequence{Hash: common.ToHex(blockSeq.Seq.Hash), Type: blockSeq.Seq.Type}
  1388  	*result = bseq
  1389  	return err
  1390  
  1391  }
  1392  
  1393  func convertHeader(header *types.Header, message *rpctypes.Header) {
  1394  
  1395  	message.BlockTime = header.GetBlockTime()
  1396  	message.Height = header.GetHeight()
  1397  	message.ParentHash = common.ToHex(header.GetParentHash())
  1398  	message.StateHash = common.ToHex(header.GetStateHash())
  1399  	message.TxHash = common.ToHex(header.GetTxHash())
  1400  	message.Version = header.GetVersion()
  1401  	message.Hash = common.ToHex(header.GetHash())
  1402  	message.TxCount = header.GetTxCount()
  1403  	message.Difficulty = header.GetDifficulty()
  1404  	if header.Signature != nil {
  1405  		message.Signature = &rpctypes.Signature{Ty: header.Signature.Ty, Pubkey: common.ToHex(header.Signature.Pubkey),
  1406  			Signature: common.ToHex(header.Signature.Signature)}
  1407  	}
  1408  }
  1409  
  1410  //GetParaTxByTitle get paraTx by title
  1411  func (c *Turingchain) GetParaTxByTitle(req types.ReqParaTxByTitle, result *interface{}) error {
  1412  	paraTxDetails, err := c.cli.GetParaTxByTitle(&req)
  1413  	if err != nil {
  1414  		return err
  1415  	}
  1416  	var paraDetails rpctypes.ParaTxDetails
  1417  	convertParaTxDetails(paraTxDetails, &paraDetails)
  1418  	*result = paraDetails
  1419  	return nil
  1420  }
  1421  
  1422  //LoadParaTxByTitle load paratx by title
  1423  func (c *Turingchain) LoadParaTxByTitle(req types.ReqHeightByTitle, result *interface{}) error {
  1424  
  1425  	reply, err := c.cli.LoadParaTxByTitle(&req)
  1426  	if err != nil {
  1427  		return err
  1428  	}
  1429  	var replyHeight rpctypes.ReplyHeightByTitle
  1430  	replyHeight.Title = reply.Title
  1431  	for _, item := range reply.Items {
  1432  		replyHeight.Items = append(replyHeight.Items, &rpctypes.BlockInfo{Height: item.Height, Hash: common.ToHex(item.Hash)})
  1433  	}
  1434  
  1435  	*result = replyHeight
  1436  	return nil
  1437  }
  1438  
  1439  func convertParaTxDetails(details *types.ParaTxDetails, message *rpctypes.ParaTxDetails) {
  1440  	for _, item := range details.Items {
  1441  		var ptxDetail rpctypes.ParaTxDetail
  1442  		var header rpctypes.Header
  1443  		convertHeader(item.Header, &header)
  1444  		ptxDetail.Header = &header
  1445  		ptxDetail.Type = item.Type
  1446  		ptxDetail.Index = item.Index
  1447  		ptxDetail.ChildHash = common.ToHex(item.ChildHash)
  1448  		for _, proof := range item.Proofs {
  1449  			ptxDetail.Proofs = append(ptxDetail.Proofs, common.ToHex(proof))
  1450  		}
  1451  		for _, detail := range item.TxDetails {
  1452  			var txDetail rpctypes.TxDetail
  1453  			txDetail.Index = detail.Index
  1454  			for _, proof := range detail.Proofs {
  1455  				txDetail.Proofs = append(txDetail.Proofs, common.ToHex(proof))
  1456  			}
  1457  
  1458  			var receipt rpctypes.ReceiptData
  1459  			receipt.Ty = detail.Receipt.Ty
  1460  			for _, log := range detail.Receipt.Logs {
  1461  				receipt.Logs = append(receipt.Logs, &rpctypes.ReceiptLog{Ty: log.Ty, Log: common.ToHex(log.Log)})
  1462  			}
  1463  			txDetail.Receipt = &receipt
  1464  			tranTx, err := rpctypes.DecodeTx(detail.Tx)
  1465  			if err != nil {
  1466  				continue
  1467  			}
  1468  			txDetail.Tx = tranTx
  1469  			ptxDetail.TxDetails = append(ptxDetail.TxDetails, &txDetail)
  1470  		}
  1471  		message.Items = append(message.Items, &ptxDetail)
  1472  	}
  1473  
  1474  }
  1475  
  1476  //GetParaTxByHeight get paraTx by block height
  1477  func (c *Turingchain) GetParaTxByHeight(req types.ReqParaTxByHeight, result *interface{}) error {
  1478  	paraTxDetails, err := c.cli.GetParaTxByHeight(&req)
  1479  	if err != nil {
  1480  		return err
  1481  	}
  1482  	var ptxDetails rpctypes.ParaTxDetails
  1483  	convertParaTxDetails(paraTxDetails, &ptxDetails)
  1484  	*result = ptxDetails
  1485  	return nil
  1486  
  1487  }
  1488  
  1489  //QueryChain querychain by chain executor
  1490  func (c *Turingchain) QueryChain(in rpctypes.ChainExecutor, result *interface{}) error {
  1491  	var qin = new(types.ChainExecutor)
  1492  	msg, err := types.QueryFunc.DecodeJSON(in.Driver, in.FuncName, in.Payload)
  1493  	if err != nil {
  1494  		log.Error("QueryChain", "DecodeJSON err", err, "driver", in.Driver,
  1495  			"func name", in.FuncName, "payload size", len(in.Payload))
  1496  		return err
  1497  	}
  1498  
  1499  	qin.Driver = in.Driver
  1500  	qin.FuncName = in.FuncName
  1501  	qin.Param = types.Encode(msg)
  1502  	if in.StateHash != "" {
  1503  		qin.StateHash = common.HexToHash(in.StateHash).Bytes()
  1504  	}
  1505  
  1506  	msg, err = c.cli.QueryChain(qin)
  1507  	if err != nil {
  1508  		log.Error("QueryChain", "err", err)
  1509  		return err
  1510  	}
  1511  	var jsonMsg json.RawMessage
  1512  	jsonMsg, err = types.PBToJSON(msg)
  1513  	if err != nil {
  1514  		return err
  1515  	}
  1516  	*result = jsonMsg
  1517  	return err
  1518  }