github.com/aergoio/aergo@v1.3.1/rpc/grpcserver.go (about)

     1  /**
     2   *  @file
     3   *  @copyright defined in aergo/LICENSE.txt
     4   */
     5  
     6  package rpc
     7  
     8  import (
     9  	"bytes"
    10  	"context"
    11  	"crypto/sha256"
    12  	"encoding/binary"
    13  	"encoding/json"
    14  	"errors"
    15  	"reflect"
    16  	"strings"
    17  	"sync"
    18  	"sync/atomic"
    19  	"time"
    20  
    21  	"github.com/aergoio/aergo-actor/actor"
    22  	"github.com/aergoio/aergo-lib/log"
    23  	"github.com/aergoio/aergo/chain"
    24  	"github.com/aergoio/aergo/consensus"
    25  	"github.com/aergoio/aergo/consensus/impl/raftv2"
    26  	"github.com/aergoio/aergo/internal/common"
    27  	"github.com/aergoio/aergo/message"
    28  	"github.com/aergoio/aergo/p2p/metric"
    29  	"github.com/aergoio/aergo/p2p/p2pcommon"
    30  	"github.com/aergoio/aergo/pkg/component"
    31  	"github.com/aergoio/aergo/types"
    32  	"github.com/golang/protobuf/ptypes/timestamp"
    33  	"google.golang.org/grpc/codes"
    34  	"google.golang.org/grpc/status"
    35  )
    36  
    37  var (
    38  	logger = log.NewLogger("rpc")
    39  )
    40  
    41  var (
    42  	ErrUninitAccessor        = errors.New("accessor is not initilized")
    43  	ErrNotSupportedConsensus = errors.New("not supported by this consensus")
    44  )
    45  
    46  type EventStream struct {
    47  	filter *types.FilterInfo
    48  	stream types.AergoRPCService_ListEventStreamServer
    49  }
    50  
    51  // AergoRPCService implements GRPC server which is defined in rpc.proto
    52  type AergoRPCService struct {
    53  	hub               *component.ComponentHub
    54  	actorHelper       p2pcommon.ActorService
    55  	consensusAccessor consensus.ConsensusAccessor //TODO refactor with actorHelper
    56  	msgHelper         message.Helper
    57  
    58  	streamID                uint32
    59  	blockStreamLock         sync.RWMutex
    60  	blockStream             map[uint32]types.AergoRPCService_ListBlockStreamServer
    61  	blockMetadataStreamLock sync.RWMutex
    62  	blockMetadataStream     map[uint32]types.AergoRPCService_ListBlockMetadataStreamServer
    63  
    64  	eventStreamLock sync.RWMutex
    65  	eventStream     map[*EventStream]*EventStream
    66  
    67  	clientAuthLock sync.RWMutex
    68  	clientAuthOn   bool
    69  	clientAuth     map[string]Authentication
    70  }
    71  
    72  // FIXME remove redundant constants
    73  const halfMinute = time.Second * 30
    74  const defaultActorTimeout = time.Second * 3
    75  
    76  var _ types.AergoRPCServiceServer = (*AergoRPCService)(nil)
    77  
    78  func (rpc *AergoRPCService) SetConsensusAccessor(ca consensus.ConsensusAccessor) {
    79  	if rpc == nil {
    80  		return
    81  	}
    82  
    83  	rpc.consensusAccessor = ca
    84  }
    85  
    86  func (rpc *AergoRPCService) Metric(ctx context.Context, req *types.MetricsRequest) (*types.Metrics, error) {
    87  	if err := rpc.checkAuth(ctx, ShowNode); err != nil {
    88  		return nil, err
    89  	}
    90  	result := &types.Metrics{}
    91  	processed := make(map[types.MetricType]interface{})
    92  	for _, mt := range req.Types {
    93  		if _, found := processed[mt]; found {
    94  			continue
    95  		}
    96  		processed[mt] = mt
    97  
    98  		switch mt {
    99  		case types.MetricType_P2P_NETWORK:
   100  			rpc.fillPeerMetrics(result)
   101  		default:
   102  			// TODO log itB
   103  		}
   104  	}
   105  
   106  	return result, nil
   107  }
   108  
   109  func (rpc *AergoRPCService) fillPeerMetrics(result *types.Metrics) {
   110  	// fill metrics for p2p
   111  	presult, err := rpc.actorHelper.CallRequestDefaultTimeout(message.P2PSvc,
   112  		&message.GetMetrics{})
   113  	if err != nil {
   114  		return
   115  	}
   116  	metrics := presult.([]*metric.PeerMetric)
   117  	mets := make([]*types.PeerMetric, len(metrics))
   118  	for i, met := range metrics {
   119  		rMet := &types.PeerMetric{PeerID: []byte(met.PeerID), SumIn: met.TotalIn(), AvrIn: met.InMetric.APS(),
   120  			SumOut: met.TotalOut(), AvrOut: met.OutMetric.APS()}
   121  		mets[i] = rMet
   122  	}
   123  
   124  	result.Peers = mets
   125  }
   126  
   127  // Blockchain handle rpc request blockchain. It has no additional input parameter
   128  func (rpc *AergoRPCService) Blockchain(ctx context.Context, in *types.Empty) (*types.BlockchainStatus, error) {
   129  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   130  		return nil, err
   131  	}
   132  	ca := rpc.actorHelper.GetChainAccessor()
   133  	last, err := ca.GetBestBlock()
   134  	if err != nil {
   135  		return nil, err
   136  	}
   137  
   138  	digest := sha256.New()
   139  	digest.Write(last.GetHeader().GetChainID())
   140  	bestChainIDHash := digest.Sum(nil)
   141  
   142  	chainInfo, err := rpc.getChainInfo(ctx)
   143  	if err != nil {
   144  		logger.Warn().Err(err).Msg("failed to get chain info in blockchain")
   145  		chainInfo = nil
   146  	}
   147  	return &types.BlockchainStatus{
   148  		BestBlockHash:   last.BlockHash(),
   149  		BestHeight:      last.GetHeader().GetBlockNo(),
   150  		ConsensusInfo:   ca.GetConsensusInfo(),
   151  		BestChainIdHash: bestChainIDHash,
   152  		ChainInfo:       chainInfo,
   153  	}, nil
   154  }
   155  
   156  // GetChainInfo handles a getchaininfo RPC request.
   157  func (rpc *AergoRPCService) GetChainInfo(ctx context.Context, in *types.Empty) (*types.ChainInfo, error) {
   158  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   159  		return nil, err
   160  	}
   161  	return rpc.getChainInfo(ctx)
   162  }
   163  
   164  func (rpc *AergoRPCService) getChainInfo(ctx context.Context) (*types.ChainInfo, error) {
   165  	chainInfo := &types.ChainInfo{}
   166  
   167  	if genesisInfo := rpc.actorHelper.GetChainAccessor().GetGenesisInfo(); genesisInfo != nil {
   168  		id := genesisInfo.ID
   169  
   170  		chainInfo.Id = &types.ChainId{
   171  			Magic:     id.Magic,
   172  			Public:    id.PublicNet,
   173  			Mainnet:   id.MainNet,
   174  			Consensus: id.Consensus,
   175  		}
   176  
   177  		if totalBalance := genesisInfo.TotalBalance(); totalBalance != nil {
   178  			chainInfo.Maxtokens = totalBalance.Bytes()
   179  		}
   180  	}
   181  
   182  	cInfo, err := rpc.GetConsensusInfo(ctx, &types.Empty{})
   183  	if err != nil {
   184  		return nil, status.Errorf(codes.Internal, err.Error())
   185  	}
   186  	chainInfo.BpNumber = uint32(len(cInfo.GetBps()))
   187  
   188  	chainInfo.Maxblocksize = uint64(chain.MaxBlockSize())
   189  
   190  	if consensus.IsDposName(chainInfo.Id.Consensus) {
   191  		if minStaking := types.GetStakingMinimum(); minStaking != nil {
   192  			chainInfo.Stakingminimum = minStaking.Bytes()
   193  		}
   194  
   195  		if total, err := rpc.actorHelper.GetChainAccessor().GetSystemValue(types.StakingTotal); total != nil {
   196  			chainInfo.Totalstaking = total.Bytes()
   197  		} else {
   198  			return nil, err
   199  		}
   200  	}
   201  
   202  	return chainInfo, nil
   203  }
   204  
   205  // ListBlockMetadata handle rpc request
   206  func (rpc *AergoRPCService) ListBlockMetadata(ctx context.Context, in *types.ListParams) (*types.BlockMetadataList, error) {
   207  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   208  		return nil, err
   209  	}
   210  	blocks, err := rpc.getBlocks(ctx, in)
   211  	if err != nil {
   212  		return nil, status.Errorf(codes.Internal, err.Error())
   213  	}
   214  	var metas []*types.BlockMetadata
   215  	for _, block := range blocks {
   216  		metas = append(metas, block.GetMetadata())
   217  	}
   218  	return &types.BlockMetadataList{Blocks: metas}, nil
   219  }
   220  
   221  // ListBlockHeaders (Deprecated) handle rpc request listblocks
   222  func (rpc *AergoRPCService) ListBlockHeaders(ctx context.Context, in *types.ListParams) (*types.BlockHeaderList, error) {
   223  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   224  		return nil, err
   225  	}
   226  	blocks, err := rpc.getBlocks(ctx, in)
   227  	if err != nil {
   228  		return nil, err
   229  	}
   230  	for _, block := range blocks {
   231  		block.Body = nil
   232  	}
   233  	return &types.BlockHeaderList{Blocks: blocks}, nil
   234  }
   235  
   236  func (rpc *AergoRPCService) getBlocks(ctx context.Context, in *types.ListParams) ([]*types.Block, error) {
   237  	var maxFetchSize uint32
   238  	// TODO refactor with almost same code is in p2pcmdblock.go
   239  	if in.Size > uint32(1000) {
   240  		maxFetchSize = uint32(1000)
   241  	} else {
   242  		maxFetchSize = in.Size
   243  	}
   244  	idx := uint32(0)
   245  	hashes := make([][]byte, 0, maxFetchSize)
   246  	blocks := make([]*types.Block, 0, maxFetchSize)
   247  	var err error
   248  	if len(in.Hash) > 0 {
   249  		hash := in.Hash
   250  		for idx < maxFetchSize {
   251  			foundBlock, futureErr := extractBlockFromFuture(rpc.hub.RequestFuture(message.ChainSvc,
   252  				&message.GetBlock{BlockHash: hash}, defaultActorTimeout, "rpc.(*AergoRPCService).ListBlockHeaders#1"))
   253  			if nil != futureErr {
   254  				if idx == 0 {
   255  					err = futureErr
   256  				}
   257  				break
   258  			}
   259  			hashes = append(hashes, foundBlock.BlockHash())
   260  			blocks = append(blocks, foundBlock)
   261  			idx++
   262  			hash = foundBlock.Header.PrevBlockHash
   263  			if len(hash) == 0 {
   264  				break
   265  			}
   266  		}
   267  		if in.Asc || in.Offset != 0 {
   268  			err = errors.New("Has unsupported param")
   269  		}
   270  	} else {
   271  		end := types.BlockNo(0)
   272  		start := types.BlockNo(in.Height) - types.BlockNo(in.Offset)
   273  		if start >= types.BlockNo(maxFetchSize) {
   274  			end = start - types.BlockNo(maxFetchSize-1)
   275  		}
   276  		if in.Asc {
   277  			for i := end; i <= start; i++ {
   278  				foundBlock, futureErr := extractBlockFromFuture(rpc.hub.RequestFuture(message.ChainSvc,
   279  					&message.GetBlockByNo{BlockNo: i}, defaultActorTimeout, "rpc.(*AergoRPCService).ListBlockHeaders#2"))
   280  				if nil != futureErr {
   281  					if i == end {
   282  						err = futureErr
   283  					}
   284  					break
   285  				}
   286  				hashes = append(hashes, foundBlock.BlockHash())
   287  				blocks = append(blocks, foundBlock)
   288  				idx++
   289  			}
   290  		} else {
   291  			for i := start; i >= end; i-- {
   292  				foundBlock, futureErr := extractBlockFromFuture(rpc.hub.RequestFuture(message.ChainSvc,
   293  					&message.GetBlockByNo{BlockNo: i}, defaultActorTimeout, "rpc.(*AergoRPCService).ListBlockHeaders#2"))
   294  				if nil != futureErr {
   295  					if i == start {
   296  						err = futureErr
   297  					}
   298  					break
   299  				}
   300  				hashes = append(hashes, foundBlock.BlockHash())
   301  				blocks = append(blocks, foundBlock)
   302  				idx++
   303  			}
   304  		}
   305  	}
   306  	return blocks, err
   307  }
   308  
   309  func (rpc *AergoRPCService) BroadcastToListBlockStream(block *types.Block) {
   310  	var err error
   311  	rpc.blockStreamLock.RLock()
   312  	for _, stream := range rpc.blockStream {
   313  		if stream != nil {
   314  			err = stream.Send(block)
   315  			if err != nil {
   316  				logger.Warn().Err(err).Msg("failed to broadcast block stream")
   317  			}
   318  		}
   319  	}
   320  	rpc.blockStreamLock.RUnlock()
   321  }
   322  
   323  func (rpc *AergoRPCService) BroadcastToListBlockMetadataStream(meta *types.BlockMetadata) {
   324  	var err error
   325  	rpc.blockMetadataStreamLock.RLock()
   326  	for _, stream := range rpc.blockMetadataStream {
   327  		if stream != nil {
   328  			err = stream.Send(meta)
   329  			if err != nil {
   330  				logger.Warn().Err(err).Msg("failed to broadcast block meta stream")
   331  			}
   332  		}
   333  	}
   334  	rpc.blockMetadataStreamLock.RUnlock()
   335  }
   336  
   337  // ListBlockStream starts a stream of new blocks
   338  func (rpc *AergoRPCService) ListBlockStream(in *types.Empty, stream types.AergoRPCService_ListBlockStreamServer) error {
   339  	streamId := atomic.AddUint32(&rpc.streamID, 1)
   340  	rpc.blockStreamLock.Lock()
   341  	rpc.blockStream[streamId] = stream
   342  	rpc.blockStreamLock.Unlock()
   343  	logger.Info().Uint32("id", streamId).Msg("block stream added")
   344  
   345  	for {
   346  		select {
   347  		case <-stream.Context().Done():
   348  			rpc.blockStreamLock.Lock()
   349  			delete(rpc.blockStream, streamId)
   350  			rpc.blockStreamLock.Unlock()
   351  			logger.Info().Uint32("id", streamId).Msg("block stream deleted")
   352  			return nil
   353  		}
   354  	}
   355  }
   356  
   357  // ListBlockMetadataStream starts a stream of new blocks' metadata
   358  func (rpc *AergoRPCService) ListBlockMetadataStream(in *types.Empty, stream types.AergoRPCService_ListBlockMetadataStreamServer) error {
   359  	streamID := atomic.AddUint32(&rpc.streamID, 1)
   360  	rpc.blockMetadataStreamLock.Lock()
   361  	rpc.blockMetadataStream[streamID] = stream
   362  	rpc.blockMetadataStreamLock.Unlock()
   363  	logger.Info().Uint32("id", streamID).Msg("block meta stream added")
   364  
   365  	for {
   366  		select {
   367  		case <-stream.Context().Done():
   368  			rpc.blockMetadataStreamLock.Lock()
   369  			delete(rpc.blockMetadataStream, streamID)
   370  			rpc.blockMetadataStreamLock.Unlock()
   371  			logger.Info().Uint32("id", streamID).Msg("block meta stream deleted")
   372  			return nil
   373  		}
   374  	}
   375  }
   376  
   377  func extractBlockFromFuture(future *actor.Future) (*types.Block, error) {
   378  	rawResponse, err := future.Result()
   379  	if err != nil {
   380  		return nil, err
   381  	}
   382  	var blockRsp *message.GetBlockRsp
   383  	switch v := rawResponse.(type) {
   384  	case message.GetBlockRsp:
   385  		blockRsp = &v
   386  	case message.GetBestBlockRsp:
   387  		blockRsp = (*message.GetBlockRsp)(&v)
   388  	case message.GetBlockByNoRsp:
   389  		blockRsp = (*message.GetBlockRsp)(&v)
   390  	default:
   391  		return nil, errors.New("Unsupported message type")
   392  	}
   393  	return extractBlock(blockRsp)
   394  }
   395  
   396  func extractBlock(from *message.GetBlockRsp) (*types.Block, error) {
   397  	if nil != from.Err {
   398  		return nil, from.Err
   399  	}
   400  	return from.Block, nil
   401  
   402  }
   403  
   404  // GetBlock handle rpc request getblock
   405  func (rpc *AergoRPCService) GetBlock(ctx context.Context, in *types.SingleBytes) (*types.Block, error) {
   406  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   407  		return nil, err
   408  	}
   409  	var result interface{}
   410  	var err error
   411  	if cap(in.Value) == 0 {
   412  		return nil, status.Errorf(codes.InvalidArgument, "Received no bytes")
   413  	}
   414  	if len(in.Value) == 32 {
   415  		result, err = rpc.hub.RequestFuture(message.ChainSvc, &message.GetBlock{BlockHash: in.Value},
   416  			defaultActorTimeout, "rpc.(*AergoRPCService).GetBlock#2").Result()
   417  	} else if len(in.Value) == 8 {
   418  		number := uint64(binary.LittleEndian.Uint64(in.Value))
   419  		result, err = rpc.hub.RequestFuture(message.ChainSvc, &message.GetBlockByNo{BlockNo: number},
   420  			defaultActorTimeout, "rpc.(*AergoRPCService).GetBlock#1").Result()
   421  	} else {
   422  		return nil, status.Errorf(codes.InvalidArgument, "Invalid input. Should be a 32 byte hash or up to 8 byte number.")
   423  	}
   424  	if err != nil {
   425  		return nil, err
   426  	}
   427  	found, err := rpc.msgHelper.ExtractBlockFromResponse(result)
   428  	if err != nil {
   429  		return nil, status.Errorf(codes.Internal, err.Error())
   430  	}
   431  	if found == nil {
   432  		return nil, status.Errorf(codes.NotFound, "Not found")
   433  	}
   434  	return found, nil
   435  }
   436  
   437  // GetBlockMetadata handle rpc request getblock
   438  func (rpc *AergoRPCService) GetBlockMetadata(ctx context.Context, in *types.SingleBytes) (*types.BlockMetadata, error) {
   439  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   440  		return nil, err
   441  	}
   442  	block, err := rpc.GetBlock(ctx, in)
   443  	if err != nil {
   444  		return nil, err
   445  	}
   446  	meta := block.GetMetadata()
   447  	return meta, nil
   448  }
   449  
   450  // GetBlockBody handle rpc request getblockbody
   451  func (rpc *AergoRPCService) GetBlockBody(ctx context.Context, in *types.BlockBodyParams) (*types.BlockBodyPaged, error) {
   452  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   453  		return nil, err
   454  	}
   455  	block, err := rpc.GetBlock(ctx, &types.SingleBytes{Value: in.Hashornumber})
   456  	if err != nil {
   457  		return nil, err
   458  	}
   459  	body := block.GetBody()
   460  
   461  	total := uint32(len(body.Txs))
   462  
   463  	var fetchSize uint32
   464  	if in.Paging.Size > uint32(1000) {
   465  		fetchSize = uint32(1000)
   466  	} else if in.Paging.Size == uint32(0) {
   467  		fetchSize = 100
   468  	} else {
   469  		fetchSize = in.Paging.Size
   470  	}
   471  
   472  	offset := in.Paging.Offset
   473  	if offset >= uint32(len(body.Txs)) {
   474  		body.Txs = []*types.Tx{}
   475  	} else {
   476  		limit := offset + fetchSize
   477  		if limit > uint32(len(body.Txs)) {
   478  			limit = uint32(len(body.Txs))
   479  		}
   480  		body.Txs = body.Txs[offset:limit]
   481  	}
   482  
   483  	response := &types.BlockBodyPaged{
   484  		Body:   body,
   485  		Total:  total,
   486  		Size:   fetchSize,
   487  		Offset: offset,
   488  	}
   489  	return response, nil
   490  }
   491  
   492  // GetTX handle rpc request gettx
   493  func (rpc *AergoRPCService) GetTX(ctx context.Context, in *types.SingleBytes) (*types.Tx, error) {
   494  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   495  		return nil, err
   496  	}
   497  	result, err := rpc.actorHelper.CallRequestDefaultTimeout(message.MemPoolSvc,
   498  		&message.MemPoolExist{Hash: in.Value})
   499  	if err != nil {
   500  		return nil, err
   501  	}
   502  	tx, err := rpc.msgHelper.ExtractTxFromResponse(result)
   503  	if err != nil {
   504  		return nil, err
   505  	}
   506  	if tx != nil {
   507  		return tx, nil
   508  	}
   509  	// TODO try find tx in blockchain, but chainservice doesn't have method yet.
   510  
   511  	return nil, status.Errorf(codes.NotFound, "not found")
   512  }
   513  
   514  // GetBlockTX handle rpc request gettx
   515  func (rpc *AergoRPCService) GetBlockTX(ctx context.Context, in *types.SingleBytes) (*types.TxInBlock, error) {
   516  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   517  		return nil, err
   518  	}
   519  	result, err := rpc.hub.RequestFuture(message.ChainSvc,
   520  		&message.GetTx{TxHash: in.Value}, defaultActorTimeout, "rpc.(*AergoRPCService).GetBlockTX").Result()
   521  	if err != nil {
   522  		return nil, err
   523  	}
   524  	rsp, ok := result.(message.GetTxRsp)
   525  	if !ok {
   526  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   527  	}
   528  	return &types.TxInBlock{Tx: rsp.Tx, TxIdx: rsp.TxIds}, rsp.Err
   529  }
   530  
   531  var emptyBytes = make([]byte, 0)
   532  
   533  // SendTX try to fill the nonce, sign, hash, chainIdHash in the transaction automatically and commit it
   534  func (rpc *AergoRPCService) SendTX(ctx context.Context, tx *types.Tx) (*types.CommitResult, error) {
   535  	if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil {
   536  		return nil, err
   537  	}
   538  	if tx.Body.Nonce == 0 {
   539  		getStateResult, err := rpc.hub.RequestFuture(message.ChainSvc,
   540  			&message.GetState{Account: tx.Body.Account}, defaultActorTimeout, "rpc.(*AergoRPCService).SendTx").Result()
   541  		if err != nil {
   542  			return nil, err
   543  		}
   544  		getStateRsp, ok := getStateResult.(message.GetStateRsp)
   545  		if !ok {
   546  			return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(getStateResult))
   547  		}
   548  		if getStateRsp.Err != nil {
   549  			return nil, status.Errorf(codes.Internal, "internal error : %s", getStateRsp.Err.Error())
   550  		}
   551  		tx.Body.Nonce = getStateRsp.State.GetNonce() + 1
   552  	}
   553  
   554  	if tx.Body.ChainIdHash == nil {
   555  		ca := rpc.actorHelper.GetChainAccessor()
   556  		last, err := ca.GetBestBlock()
   557  		if err != nil {
   558  			return nil, err
   559  		}
   560  		tx.Body.ChainIdHash = common.Hasher(last.GetHeader().GetChainID())
   561  	}
   562  
   563  	signTxResult, err := rpc.hub.RequestFutureResult(message.AccountsSvc,
   564  		&message.SignTx{Tx: tx, Requester: tx.Body.Account}, defaultActorTimeout, "rpc.(*AergoRPCService).SendTX")
   565  	if err != nil {
   566  		if err == component.ErrHubUnregistered {
   567  			return nil, status.Errorf(codes.Unavailable, "Unavailable personal feature")
   568  		}
   569  		return nil, status.Errorf(codes.Internal, err.Error())
   570  	}
   571  
   572  	signTxRsp, ok := signTxResult.(*message.SignTxRsp)
   573  	if !ok {
   574  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(signTxResult))
   575  	}
   576  	if signTxRsp.Err != nil {
   577  		return nil, signTxRsp.Err
   578  	}
   579  	tx = signTxRsp.Tx
   580  	memPoolPutResult, err := rpc.hub.RequestFuture(message.MemPoolSvc,
   581  		&message.MemPoolPut{Tx: tx},
   582  		defaultActorTimeout, "rpc.(*AergoRPCService).SendTX").Result()
   583  	memPoolPutRsp, ok := memPoolPutResult.(*message.MemPoolPutRsp)
   584  	if !ok {
   585  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(memPoolPutResult))
   586  	}
   587  	resultErr := memPoolPutRsp.Err
   588  	if resultErr != nil {
   589  		return &types.CommitResult{Hash: tx.Hash, Error: convertError(resultErr), Detail: resultErr.Error()}, err
   590  	}
   591  	return &types.CommitResult{Hash: tx.Hash, Error: convertError(resultErr)}, err
   592  }
   593  
   594  // CommitTX handle rpc request commit
   595  func (rpc *AergoRPCService) CommitTX(ctx context.Context, in *types.TxList) (*types.CommitResultList, error) {
   596  	// TODO: check validity
   597  	//if bytes.Equal(emptyBytes, in.Hash) {
   598  	//	return nil, status.Errorf(codes.InvalidArgument, "invalid hash")
   599  	//}
   600  	if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil {
   601  		return nil, err
   602  	}
   603  	if in.Txs == nil {
   604  		return nil, status.Errorf(codes.InvalidArgument, "input tx is empty")
   605  	}
   606  	rs := make([]*types.CommitResult, len(in.Txs))
   607  	futures := make([]*actor.Future, len(in.Txs))
   608  	results := &types.CommitResultList{Results: rs}
   609  	//results := &types.CommitResultList{}
   610  	cnt := 0
   611  
   612  	for i, tx := range in.Txs {
   613  		hash := tx.Hash
   614  		var r types.CommitResult
   615  		r.Hash = hash
   616  
   617  		calculated := tx.CalculateTxHash()
   618  
   619  		if !bytes.Equal(hash, calculated) {
   620  			r.Error = types.CommitStatus_TX_INVALID_HASH
   621  		}
   622  		results.Results[i] = &r
   623  		cnt++
   624  
   625  		//send tx message to mempool
   626  		f := rpc.hub.RequestFuture(message.MemPoolSvc,
   627  			&message.MemPoolPut{Tx: tx},
   628  			defaultActorTimeout, "rpc.(*AergoRPCService).CommitTX")
   629  		futures[i] = f
   630  	}
   631  	for i, future := range futures {
   632  		result, err := future.Result()
   633  		if err != nil {
   634  			return nil, err
   635  		}
   636  		rsp, ok := result.(*message.MemPoolPutRsp)
   637  		if !ok {
   638  			err = status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   639  		} else {
   640  			err = rsp.Err
   641  		}
   642  		results.Results[i].Error = convertError(err)
   643  		if err != nil {
   644  			results.Results[i].Detail = err.Error()
   645  		}
   646  	}
   647  
   648  	return results, nil
   649  }
   650  
   651  // GetState handle rpc request getstate
   652  func (rpc *AergoRPCService) GetState(ctx context.Context, in *types.SingleBytes) (*types.State, error) {
   653  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   654  		return nil, err
   655  	}
   656  	result, err := rpc.hub.RequestFuture(message.ChainSvc,
   657  		&message.GetState{Account: in.Value}, defaultActorTimeout, "rpc.(*AergoRPCService).GetState").Result()
   658  	if err != nil {
   659  		return nil, err
   660  	}
   661  	rsp, ok := result.(message.GetStateRsp)
   662  	if !ok {
   663  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   664  	}
   665  	return rsp.State, rsp.Err
   666  }
   667  
   668  // GetStateAndProof handle rpc request getstateproof
   669  func (rpc *AergoRPCService) GetStateAndProof(ctx context.Context, in *types.AccountAndRoot) (*types.AccountProof, error) {
   670  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   671  		return nil, err
   672  	}
   673  	result, err := rpc.hub.RequestFuture(message.ChainSvc,
   674  		&message.GetStateAndProof{Account: in.Account, Root: in.Root, Compressed: in.Compressed}, defaultActorTimeout, "rpc.(*AergoRPCService).GetStateAndProof").Result()
   675  	if err != nil {
   676  		return nil, err
   677  	}
   678  	rsp, ok := result.(message.GetStateAndProofRsp)
   679  	if !ok {
   680  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   681  	}
   682  	return rsp.StateProof, rsp.Err
   683  }
   684  
   685  // CreateAccount handle rpc request newaccount
   686  func (rpc *AergoRPCService) CreateAccount(ctx context.Context, in *types.Personal) (*types.Account, error) {
   687  	if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil {
   688  		return nil, err
   689  	}
   690  	result, err := rpc.hub.RequestFutureResult(message.AccountsSvc,
   691  		&message.CreateAccount{Passphrase: in.Passphrase}, defaultActorTimeout, "rpc.(*AergoRPCService).CreateAccount")
   692  	if err != nil {
   693  		if err == component.ErrHubUnregistered {
   694  			return nil, status.Errorf(codes.Unavailable, "Unavailable personal feature")
   695  		}
   696  		return nil, status.Errorf(codes.Internal, err.Error())
   697  	}
   698  	/*
   699  		//same code but not good at folding in editor
   700  		switch err {
   701  		case nil:
   702  		case component.ErrHubUnregistered:
   703  			return nil, status.Errorf(codes.Unavailable, "Unavailable personal feature")
   704  		default:
   705  			return nil, status.Errorf(codes.Internal, err.Error())
   706  		}
   707  	*/
   708  
   709  	rsp, ok := result.(*message.CreateAccountRsp)
   710  	if !ok {
   711  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   712  	}
   713  	return rsp.Account, nil
   714  	/*
   715  		//it's better?
   716  		switch rsp := result.(type) {
   717  		case *message.CreateAccountRsp:
   718  			return rsp.Accounts, nil
   719  		default:
   720  			return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   721  		}
   722  	*/
   723  }
   724  
   725  // GetAccounts handle rpc request getaccounts
   726  func (rpc *AergoRPCService) GetAccounts(ctx context.Context, in *types.Empty) (*types.AccountList, error) {
   727  	if err := rpc.checkAuth(ctx, ShowNode); err != nil {
   728  		return nil, err
   729  	}
   730  	result, err := rpc.hub.RequestFutureResult(message.AccountsSvc,
   731  		&message.GetAccounts{}, defaultActorTimeout, "rpc.(*AergoRPCService).GetAccounts")
   732  	if err != nil {
   733  		if err == component.ErrHubUnregistered {
   734  			return nil, status.Errorf(codes.Unavailable, "Unavailable personal feature")
   735  		}
   736  		return nil, status.Errorf(codes.Internal, err.Error())
   737  	}
   738  
   739  	rsp, ok := result.(*message.GetAccountsRsp)
   740  	if !ok {
   741  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   742  	}
   743  	return rsp.Accounts, nil
   744  }
   745  
   746  // LockAccount handle rpc request lockaccount
   747  func (rpc *AergoRPCService) LockAccount(ctx context.Context, in *types.Personal) (*types.Account, error) {
   748  	if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil {
   749  		return nil, err
   750  	}
   751  	result, err := rpc.hub.RequestFutureResult(message.AccountsSvc,
   752  		&message.LockAccount{Account: in.Account, Passphrase: in.Passphrase},
   753  		defaultActorTimeout, "rpc.(*AergoRPCService).LockAccount")
   754  	if err != nil {
   755  		if err == component.ErrHubUnregistered {
   756  			return nil, status.Errorf(codes.Unavailable, "Unavailable personal feature")
   757  		}
   758  		return nil, status.Errorf(codes.Internal, err.Error())
   759  	}
   760  
   761  	rsp, ok := result.(*message.AccountRsp)
   762  	if !ok {
   763  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   764  	}
   765  	return rsp.Account, rsp.Err
   766  }
   767  
   768  // UnlockAccount handle rpc request unlockaccount
   769  func (rpc *AergoRPCService) UnlockAccount(ctx context.Context, in *types.Personal) (*types.Account, error) {
   770  	if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil {
   771  		return nil, err
   772  	}
   773  	result, err := rpc.hub.RequestFutureResult(message.AccountsSvc,
   774  		&message.UnlockAccount{Account: in.Account, Passphrase: in.Passphrase},
   775  		defaultActorTimeout, "rpc.(*AergoRPCService).UnlockAccount")
   776  	if err != nil {
   777  		if err == component.ErrHubUnregistered {
   778  			return nil, status.Errorf(codes.Unavailable, "Unavailable personal feature")
   779  		}
   780  		return nil, status.Errorf(codes.Internal, err.Error())
   781  	}
   782  
   783  	rsp, ok := result.(*message.AccountRsp)
   784  	if !ok {
   785  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   786  	}
   787  	return rsp.Account, rsp.Err
   788  }
   789  
   790  func (rpc *AergoRPCService) ImportAccount(ctx context.Context, in *types.ImportFormat) (*types.Account, error) {
   791  	if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil {
   792  		return nil, err
   793  	}
   794  	result, err := rpc.hub.RequestFutureResult(message.AccountsSvc,
   795  		&message.ImportAccount{Wif: in.Wif.Value, OldPass: in.Oldpass, NewPass: in.Newpass},
   796  		defaultActorTimeout, "rpc.(*AergoRPCService).ImportAccount")
   797  	if err != nil {
   798  		if err == component.ErrHubUnregistered {
   799  			return nil, status.Errorf(codes.Unavailable, "Unavailable personal feature")
   800  		}
   801  		return nil, status.Errorf(codes.Internal, err.Error())
   802  	}
   803  
   804  	rsp, ok := result.(*message.ImportAccountRsp)
   805  	if !ok {
   806  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   807  	}
   808  	return rsp.Account, rsp.Err
   809  }
   810  
   811  func (rpc *AergoRPCService) ExportAccount(ctx context.Context, in *types.Personal) (*types.SingleBytes, error) {
   812  	if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil {
   813  		return nil, err
   814  	}
   815  	result, err := rpc.hub.RequestFutureResult(message.AccountsSvc,
   816  		&message.ExportAccount{Account: in.Account, Pass: in.Passphrase},
   817  		defaultActorTimeout, "rpc.(*AergoRPCService).ExportAccount")
   818  	if err != nil {
   819  		if err == component.ErrHubUnregistered {
   820  			return nil, status.Errorf(codes.Unavailable, "Unavailable personal feature")
   821  		}
   822  		return nil, status.Errorf(codes.Internal, err.Error())
   823  	}
   824  
   825  	rsp, ok := result.(*message.ExportAccountRsp)
   826  	if !ok {
   827  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   828  	}
   829  	return &types.SingleBytes{Value: rsp.Wif}, rsp.Err
   830  }
   831  
   832  // SignTX handle rpc request signtx
   833  func (rpc *AergoRPCService) SignTX(ctx context.Context, in *types.Tx) (*types.Tx, error) {
   834  	if err := rpc.checkAuth(ctx, WriteBlockChain); err != nil {
   835  		return nil, err
   836  	}
   837  	result, err := rpc.hub.RequestFutureResult(message.AccountsSvc,
   838  		&message.SignTx{Tx: in}, defaultActorTimeout, "rpc.(*AergoRPCService).SignTX")
   839  	if err != nil {
   840  		if err == component.ErrHubUnregistered {
   841  			return nil, status.Errorf(codes.Unavailable, "Unavailable personal feature")
   842  		}
   843  		return nil, status.Errorf(codes.Internal, err.Error())
   844  	}
   845  
   846  	rsp, ok := result.(*message.SignTxRsp)
   847  	if !ok {
   848  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   849  	}
   850  	return rsp.Tx, rsp.Err
   851  }
   852  
   853  // VerifyTX handle rpc request verifytx
   854  func (rpc *AergoRPCService) VerifyTX(ctx context.Context, in *types.Tx) (*types.VerifyResult, error) {
   855  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   856  		return nil, err
   857  	}
   858  	//TODO : verify without account service
   859  	result, err := rpc.hub.RequestFutureResult(message.AccountsSvc,
   860  		&message.VerifyTx{Tx: in}, defaultActorTimeout, "rpc.(*AergoRPCService).VerifyTX")
   861  	if err != nil {
   862  		if err == component.ErrHubUnregistered {
   863  			return nil, status.Errorf(codes.Unavailable, "Unavailable personal feature")
   864  		}
   865  		return nil, status.Errorf(codes.Internal, err.Error())
   866  	}
   867  
   868  	rsp, ok := result.(*message.VerifyTxRsp)
   869  	if !ok {
   870  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   871  	}
   872  	ret := &types.VerifyResult{Tx: rsp.Tx}
   873  	if rsp.Err == types.ErrSignNotMatch {
   874  		ret.Error = types.VerifyStatus_VERIFY_STATUS_SIGN_NOT_MATCH
   875  	} else {
   876  		ret.Error = types.VerifyStatus_VERIFY_STATUS_OK
   877  	}
   878  	return ret, nil
   879  }
   880  
   881  // GetPeers handle rpc request getpeers
   882  func (rpc *AergoRPCService) GetPeers(ctx context.Context, in *types.PeersParams) (*types.PeerList, error) {
   883  	if err := rpc.checkAuth(ctx, ShowNode); err != nil {
   884  		return nil, err
   885  	}
   886  	result, err := rpc.hub.RequestFuture(message.P2PSvc,
   887  		&message.GetPeers{in.NoHidden, in.ShowSelf}, halfMinute, "rpc.(*AergoRPCService).GetPeers").Result()
   888  	if err != nil {
   889  		return nil, err
   890  	}
   891  	rsp, ok := result.(*message.GetPeersRsp)
   892  	if !ok {
   893  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   894  	}
   895  
   896  	ret := &types.PeerList{Peers: make([]*types.Peer, 0, len(rsp.Peers))}
   897  	for _, pi := range rsp.Peers {
   898  		blkNotice := &types.NewBlockNotice{BlockHash: pi.LastBlockHash, BlockNo: pi.LastBlockNumber}
   899  		peer := &types.Peer{Address: pi.Addr, State: int32(pi.State), Bestblock: blkNotice, LashCheck: pi.CheckTime.UnixNano(), Hidden: pi.Hidden, Selfpeer: pi.Self, Version: pi.Version}
   900  		ret.Peers = append(ret.Peers, peer)
   901  	}
   902  
   903  	return ret, nil
   904  }
   905  
   906  // NodeState handle rpc request nodestate
   907  func (rpc *AergoRPCService) NodeState(ctx context.Context, in *types.NodeReq) (*types.SingleBytes, error) {
   908  	if err := rpc.checkAuth(ctx, ShowNode); err != nil {
   909  		return nil, err
   910  	}
   911  	timeout := int64(binary.LittleEndian.Uint64(in.Timeout))
   912  	component := string(in.Component)
   913  
   914  	logger.Debug().Str("comp", component).Int64("timeout", timeout).Msg("nodestate")
   915  
   916  	statics, err := rpc.hub.Statistics(time.Duration(timeout)*time.Second, component)
   917  	if err != nil {
   918  		return nil, err
   919  	}
   920  
   921  	data, err := json.MarshalIndent(statics, "", "\t")
   922  	if err != nil {
   923  		return nil, err
   924  	}
   925  	return &types.SingleBytes{Value: data}, nil
   926  }
   927  
   928  //GetVotes handle rpc request getvotes
   929  func (rpc *AergoRPCService) GetVotes(ctx context.Context, in *types.VoteParams) (*types.VoteList, error) {
   930  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   931  		return nil, err
   932  	}
   933  
   934  	result, err := rpc.hub.RequestFuture(message.ChainSvc,
   935  		&message.GetElected{Id: in.GetId(), N: in.GetCount()}, defaultActorTimeout, "rpc.(*AergoRPCService).GetVote").Result()
   936  
   937  	if err != nil {
   938  		return nil, err
   939  	}
   940  	rsp, ok := result.(*message.GetVoteRsp)
   941  	if !ok {
   942  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   943  	}
   944  	return rsp.Top, rsp.Err
   945  }
   946  
   947  func (rpc *AergoRPCService) GetAccountVotes(ctx context.Context, in *types.AccountAddress) (*types.AccountVoteInfo, error) {
   948  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   949  		return nil, err
   950  	}
   951  	ids := []string{}
   952  	for _, v := range types.AllVotes {
   953  		ids = append(ids, v[2:])
   954  	}
   955  	result, err := rpc.hub.RequestFuture(message.ChainSvc,
   956  		&message.GetVote{Addr: in.Value, Ids: ids}, defaultActorTimeout, "rpc.(*AergoRPCService).GetAccountVote").Result()
   957  	if err != nil {
   958  		return nil, err
   959  	}
   960  	rsp, ok := result.(*message.GetAccountVoteRsp)
   961  	if !ok {
   962  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   963  	}
   964  	return rsp.Info, rsp.Err
   965  }
   966  
   967  //GetStaking handle rpc request getstaking
   968  func (rpc *AergoRPCService) GetStaking(ctx context.Context, in *types.AccountAddress) (*types.Staking, error) {
   969  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   970  		return nil, err
   971  	}
   972  	var err error
   973  	var result interface{}
   974  
   975  	if len(in.Value) <= types.AddressLength {
   976  		result, err = rpc.hub.RequestFuture(message.ChainSvc,
   977  			&message.GetStaking{Addr: in.Value}, defaultActorTimeout, "rpc.(*AergoRPCService).GetStaking").Result()
   978  		if err != nil {
   979  			return nil, err
   980  		}
   981  	} else {
   982  		return nil, status.Errorf(codes.InvalidArgument, "Only support valid address")
   983  	}
   984  	rsp, ok := result.(*message.GetStakingRsp)
   985  	if !ok {
   986  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
   987  	}
   988  	return rsp.Staking, rsp.Err
   989  }
   990  
   991  func (rpc *AergoRPCService) GetNameInfo(ctx context.Context, in *types.Name) (*types.NameInfo, error) {
   992  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
   993  		return nil, err
   994  	}
   995  	result, err := rpc.hub.RequestFuture(message.ChainSvc,
   996  		&message.GetNameInfo{Name: in.Name, BlockNo: in.BlockNo}, defaultActorTimeout, "rpc.(*AergoRPCService).GetName").Result()
   997  	if err != nil {
   998  		return nil, err
   999  	}
  1000  	rsp, ok := result.(*message.GetNameInfoRsp)
  1001  	if !ok {
  1002  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
  1003  	}
  1004  	if rsp.Err == types.ErrNameNotFound {
  1005  		return rsp.Owner, status.Errorf(codes.NotFound, rsp.Err.Error())
  1006  	}
  1007  	return rsp.Owner, rsp.Err
  1008  }
  1009  
  1010  func (rpc *AergoRPCService) GetReceipt(ctx context.Context, in *types.SingleBytes) (*types.Receipt, error) {
  1011  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
  1012  		return nil, err
  1013  	}
  1014  	result, err := rpc.hub.RequestFuture(message.ChainSvc,
  1015  		&message.GetReceipt{TxHash: in.Value}, defaultActorTimeout, "rpc.(*AergoRPCService).GetReceipt").Result()
  1016  	if err != nil {
  1017  		return nil, err
  1018  	}
  1019  	rsp, ok := result.(message.GetReceiptRsp)
  1020  	if !ok {
  1021  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
  1022  	}
  1023  	return rsp.Receipt, rsp.Err
  1024  }
  1025  
  1026  func (rpc *AergoRPCService) GetABI(ctx context.Context, in *types.SingleBytes) (*types.ABI, error) {
  1027  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
  1028  		return nil, err
  1029  	}
  1030  	result, err := rpc.hub.RequestFuture(message.ChainSvc,
  1031  		&message.GetABI{Contract: in.Value}, defaultActorTimeout, "rpc.(*AergoRPCService).GetABI").Result()
  1032  	if err != nil {
  1033  		return nil, err
  1034  	}
  1035  	rsp, ok := result.(message.GetABIRsp)
  1036  	if !ok {
  1037  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
  1038  	}
  1039  	return rsp.ABI, rsp.Err
  1040  }
  1041  
  1042  func (rpc *AergoRPCService) QueryContract(ctx context.Context, in *types.Query) (*types.SingleBytes, error) {
  1043  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
  1044  		return nil, err
  1045  	}
  1046  	result, err := rpc.hub.RequestFuture(message.ChainSvc,
  1047  		&message.GetQuery{Contract: in.ContractAddress, Queryinfo: in.Queryinfo}, defaultActorTimeout, "rpc.(*AergoRPCService).QueryContract").Result()
  1048  	if err != nil {
  1049  		return nil, err
  1050  	}
  1051  	rsp, ok := result.(message.GetQueryRsp)
  1052  	if !ok {
  1053  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
  1054  	}
  1055  	return &types.SingleBytes{Value: rsp.Result}, rsp.Err
  1056  }
  1057  
  1058  // QueryContractState queries the state of a contract state variable without executing a contract function.
  1059  func (rpc *AergoRPCService) QueryContractState(ctx context.Context, in *types.StateQuery) (*types.StateQueryProof, error) {
  1060  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
  1061  		return nil, err
  1062  	}
  1063  	result, err := rpc.hub.RequestFuture(message.ChainSvc,
  1064  		&message.GetStateQuery{ContractAddress: in.ContractAddress, StorageKeys: in.StorageKeys, Root: in.Root, Compressed: in.Compressed}, defaultActorTimeout, "rpc.(*AergoRPCService).GetStateQuery").Result()
  1065  	if err != nil {
  1066  		return nil, err
  1067  	}
  1068  	rsp, ok := result.(message.GetStateQueryRsp)
  1069  	if !ok {
  1070  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
  1071  	}
  1072  	return rsp.Result, rsp.Err
  1073  }
  1074  
  1075  func toTimestamp(time time.Time) *timestamp.Timestamp {
  1076  	return &timestamp.Timestamp{
  1077  		Seconds: time.Unix(),
  1078  		Nanos:   int32(time.Nanosecond())}
  1079  }
  1080  
  1081  func fromTimestamp(timestamp *timestamp.Timestamp) time.Time {
  1082  	return time.Unix(timestamp.Seconds, int64(timestamp.Nanos))
  1083  }
  1084  
  1085  func (rpc *AergoRPCService) ListEventStream(in *types.FilterInfo, stream types.AergoRPCService_ListEventStreamServer) error {
  1086  	err := in.ValidateCheck(0)
  1087  	if err != nil {
  1088  		return err
  1089  	}
  1090  	_, err = in.GetExArgFilter()
  1091  	if err != nil {
  1092  		return err
  1093  	}
  1094  
  1095  	eventStream := &EventStream{in, stream}
  1096  	rpc.eventStreamLock.Lock()
  1097  	rpc.eventStream[eventStream] = eventStream
  1098  	rpc.eventStreamLock.Unlock()
  1099  
  1100  	for {
  1101  		select {
  1102  		case <-eventStream.stream.Context().Done():
  1103  			rpc.eventStreamLock.Lock()
  1104  			delete(rpc.eventStream, eventStream)
  1105  			rpc.eventStreamLock.Unlock()
  1106  			return nil
  1107  		}
  1108  	}
  1109  }
  1110  
  1111  func (rpc *AergoRPCService) BroadcastToEventStream(events []*types.Event) error {
  1112  	var err error
  1113  	rpc.eventStreamLock.RLock()
  1114  	defer rpc.eventStreamLock.RUnlock()
  1115  
  1116  	for _, es := range rpc.eventStream {
  1117  		if es != nil {
  1118  			argFilter, _ := es.filter.GetExArgFilter()
  1119  			for _, event := range events {
  1120  				if event.Filter(es.filter, argFilter) {
  1121  					err = es.stream.Send(event)
  1122  					if err != nil {
  1123  						logger.Warn().Err(err).Msg("failed to broadcast block stream")
  1124  						break
  1125  					}
  1126  				}
  1127  			}
  1128  		}
  1129  	}
  1130  	return nil
  1131  }
  1132  
  1133  func (rpc *AergoRPCService) ListEvents(ctx context.Context, in *types.FilterInfo) (*types.EventList, error) {
  1134  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
  1135  		return nil, err
  1136  	}
  1137  	result, err := rpc.hub.RequestFuture(message.ChainSvc,
  1138  		&message.ListEvents{Filter: in}, defaultActorTimeout, "rpc.(*AergoRPCService).ListEvents").Result()
  1139  	if err != nil {
  1140  		return nil, err
  1141  	}
  1142  	rsp, ok := result.(*message.ListEventsRsp)
  1143  	if !ok {
  1144  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
  1145  	}
  1146  	return &types.EventList{Events: rsp.Events}, rsp.Err
  1147  }
  1148  
  1149  func (rpc *AergoRPCService) GetServerInfo(ctx context.Context, in *types.KeyParams) (*types.ServerInfo, error) {
  1150  	if err := rpc.checkAuth(ctx, ShowNode); err != nil {
  1151  		return nil, err
  1152  	}
  1153  	result, err := rpc.hub.RequestFuture(message.RPCSvc,
  1154  		&message.GetServerInfo{Categories: in.Key}, defaultActorTimeout, "rpc.(*AergoRPCService).GetServerInfo").Result()
  1155  	if err != nil {
  1156  		return nil, err
  1157  	}
  1158  	rsp, ok := result.(*types.ServerInfo)
  1159  	if !ok {
  1160  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
  1161  	}
  1162  	return rsp, nil
  1163  }
  1164  
  1165  // GetConsensusInfo handle rpc request blockchain. It has no additional input parameter
  1166  func (rpc *AergoRPCService) GetConsensusInfo(ctx context.Context, in *types.Empty) (*types.ConsensusInfo, error) {
  1167  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
  1168  		return nil, err
  1169  	}
  1170  	if rpc.consensusAccessor == nil {
  1171  		return nil, ErrUninitAccessor
  1172  	}
  1173  
  1174  	return rpc.consensusAccessor.ConsensusInfo(), nil
  1175  }
  1176  
  1177  // ChainStat handles rpc request chainstat.
  1178  func (rpc *AergoRPCService) ChainStat(ctx context.Context, in *types.Empty) (*types.ChainStats, error) {
  1179  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
  1180  		return nil, err
  1181  	}
  1182  	ca := rpc.actorHelper.GetChainAccessor()
  1183  	if ca == nil {
  1184  		return nil, ErrUninitAccessor
  1185  	}
  1186  	return &types.ChainStats{Report: ca.GetChainStats()}, nil
  1187  }
  1188  
  1189  func (rpc *AergoRPCService) ChangeMembership(ctx context.Context, in *types.MembershipChange) (*types.MembershipChangeReply, error) {
  1190  	if err := rpc.checkAuth(ctx, ControlNode); err != nil {
  1191  		return nil, err
  1192  	}
  1193  	if rpc.consensusAccessor == nil {
  1194  		return nil, ErrUninitAccessor
  1195  	}
  1196  
  1197  	if genesisInfo := rpc.actorHelper.GetChainAccessor().GetGenesisInfo(); genesisInfo != nil {
  1198  		if genesisInfo.ID.Consensus != raftv2.GetName() {
  1199  			return nil, ErrNotSupportedConsensus
  1200  		}
  1201  	}
  1202  
  1203  	member, err := rpc.consensusAccessor.ConfChange(in)
  1204  	if err != nil {
  1205  		return nil, err
  1206  	}
  1207  
  1208  	reply := &types.MembershipChangeReply{Attr: &types.MemberAttr{ID: uint64(member.ID), Name: member.Name, Address: member.Address, PeerID: []byte(types.PeerID(member.PeerID))}}
  1209  	return reply, nil
  1210  }
  1211  
  1212  //GetEnterpriseConfig return aergo.enterprise configure values. key "ADMINS" is for getting register admin addresses and "ALL" is for getting all key list.
  1213  func (rpc *AergoRPCService) GetEnterpriseConfig(ctx context.Context, in *types.EnterpriseConfigKey) (*types.EnterpriseConfig, error) {
  1214  	genensis := rpc.actorHelper.GetChainAccessor().GetGenesisInfo()
  1215  	if genensis.PublicNet() {
  1216  		return nil, status.Error(codes.Unavailable, "not supported in public")
  1217  	}
  1218  
  1219  	if err := rpc.checkAuth(ctx, ReadBlockChain); err != nil {
  1220  		return nil, err
  1221  	}
  1222  	result, err := rpc.hub.RequestFuture(message.ChainSvc,
  1223  		&message.GetEnterpriseConf{Key: in.Key}, defaultActorTimeout, "rpc.(*AergoRPCService).GetEnterpiseConfig").Result()
  1224  	if err != nil {
  1225  		return nil, err
  1226  	}
  1227  	rsp, ok := result.(*message.GetEnterpriseConfRsp)
  1228  	if !ok {
  1229  		return nil, status.Errorf(codes.Internal, "internal type (%v) error", reflect.TypeOf(result))
  1230  	}
  1231  	return rsp.Conf, nil
  1232  }
  1233  
  1234  func (rpc *AergoRPCService) GetConfChangeProgress(ctx context.Context, in *types.SingleBytes) (*types.ConfChangeProgress, error) {
  1235  	var (
  1236  		progress *types.ConfChangeProgress
  1237  		err      error
  1238  	)
  1239  
  1240  	genesis := rpc.actorHelper.GetChainAccessor().GetGenesisInfo()
  1241  	if genesis.PublicNet() {
  1242  		return nil, status.Error(codes.Unavailable, "not supported in public")
  1243  	}
  1244  
  1245  	if strings.ToLower(genesis.ConsensusType()) != consensus.ConsensusName[consensus.ConsensusRAFT] {
  1246  		return nil, status.Error(codes.Unavailable, "not supported if not raft consensus")
  1247  	}
  1248  
  1249  	if err = rpc.checkAuth(ctx, ReadBlockChain); err != nil {
  1250  		return nil, err
  1251  	}
  1252  
  1253  	if rpc.consensusAccessor == nil {
  1254  		return nil, ErrUninitAccessor
  1255  	}
  1256  
  1257  	if len(in.Value) != 8 {
  1258  		return nil, status.Errorf(codes.InvalidArgument, "Invalid input. Request ID should be a 8 byte number.")
  1259  	}
  1260  
  1261  	reqID := uint64(binary.LittleEndian.Uint64(in.Value))
  1262  
  1263  	if progress, err = rpc.consensusAccessor.ConfChangeInfo(reqID); err != nil {
  1264  		return nil, err
  1265  	}
  1266  
  1267  	if progress == nil {
  1268  		return nil, status.Errorf(codes.NotFound, "not found")
  1269  	}
  1270  
  1271  	return progress, nil
  1272  }