github.com/Finschia/finschia-sdk@v0.48.1/server/rosetta/lib/internal/service/data.go (about)

     1  package service
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/coinbase/rosetta-sdk-go/types"
     7  
     8  	"github.com/Finschia/finschia-sdk/server/rosetta/lib/errors"
     9  	crgtypes "github.com/Finschia/finschia-sdk/server/rosetta/lib/types"
    10  )
    11  
    12  // AccountBalance retrieves the account balance of an address
    13  // rosetta requires us to fetch the block information too
    14  func (on OnlineNetwork) AccountBalance(ctx context.Context, request *types.AccountBalanceRequest) (*types.AccountBalanceResponse, *types.Error) {
    15  	var (
    16  		height int64
    17  		block  crgtypes.BlockResponse
    18  		err    error
    19  	)
    20  
    21  	switch {
    22  	case request.BlockIdentifier == nil:
    23  		block, err = on.client.BlockByHeight(ctx, nil)
    24  		if err != nil {
    25  			return nil, errors.ToRosetta(err)
    26  		}
    27  	case request.BlockIdentifier.Hash != nil:
    28  		block, err = on.client.BlockByHash(ctx, *request.BlockIdentifier.Hash)
    29  		if err != nil {
    30  			return nil, errors.ToRosetta(err)
    31  		}
    32  		height = block.Block.Index
    33  	case request.BlockIdentifier.Index != nil:
    34  		height = *request.BlockIdentifier.Index
    35  		block, err = on.client.BlockByHeight(ctx, &height)
    36  		if err != nil {
    37  			return nil, errors.ToRosetta(err)
    38  		}
    39  	}
    40  
    41  	accountCoins, err := on.client.Balances(ctx, request.AccountIdentifier.Address, &height)
    42  	if err != nil {
    43  		return nil, errors.ToRosetta(err)
    44  	}
    45  
    46  	return &types.AccountBalanceResponse{
    47  		BlockIdentifier: block.Block,
    48  		Balances:        accountCoins,
    49  		Metadata:        nil,
    50  	}, nil
    51  }
    52  
    53  // Block gets the transactions in the given block
    54  func (on OnlineNetwork) Block(ctx context.Context, request *types.BlockRequest) (*types.BlockResponse, *types.Error) {
    55  	var (
    56  		blockResponse crgtypes.BlockTransactionsResponse
    57  		err           error
    58  	)
    59  	// block identifier is assumed not to be nil as rosetta will do this check for us
    60  	// check if we have to query via hash or block number
    61  	switch {
    62  	case request.BlockIdentifier.Hash != nil:
    63  		blockResponse, err = on.client.BlockTransactionsByHash(ctx, *request.BlockIdentifier.Hash)
    64  		if err != nil {
    65  			return nil, errors.ToRosetta(err)
    66  		}
    67  	case request.BlockIdentifier.Index != nil:
    68  		blockResponse, err = on.client.BlockTransactionsByHeight(ctx, request.BlockIdentifier.Index)
    69  		if err != nil {
    70  			return nil, errors.ToRosetta(err)
    71  		}
    72  	default:
    73  		err := errors.WrapError(errors.ErrBadArgument, "at least one of hash or index needs to be specified")
    74  		return nil, errors.ToRosetta(err)
    75  	}
    76  
    77  	return &types.BlockResponse{
    78  		Block: &types.Block{
    79  			BlockIdentifier:       blockResponse.Block,
    80  			ParentBlockIdentifier: blockResponse.ParentBlock,
    81  			Timestamp:             blockResponse.MillisecondTimestamp,
    82  			Transactions:          blockResponse.Transactions,
    83  			Metadata:              nil,
    84  		},
    85  		OtherTransactions: nil,
    86  	}, nil
    87  }
    88  
    89  // BlockTransaction gets the given transaction in the specified block, we do not need to check the block itself too
    90  // due to the fact that tendermint achieves instant finality
    91  func (on OnlineNetwork) BlockTransaction(ctx context.Context, request *types.BlockTransactionRequest) (*types.BlockTransactionResponse, *types.Error) {
    92  	tx, err := on.client.GetTx(ctx, request.TransactionIdentifier.Hash)
    93  	if err != nil {
    94  		return nil, errors.ToRosetta(err)
    95  	}
    96  
    97  	return &types.BlockTransactionResponse{
    98  		Transaction: tx,
    99  	}, nil
   100  }
   101  
   102  // Mempool fetches the transactions contained in the mempool
   103  func (on OnlineNetwork) Mempool(ctx context.Context, _ *types.NetworkRequest) (*types.MempoolResponse, *types.Error) {
   104  	txs, err := on.client.Mempool(ctx)
   105  	if err != nil {
   106  		return nil, errors.ToRosetta(err)
   107  	}
   108  
   109  	return &types.MempoolResponse{
   110  		TransactionIdentifiers: txs,
   111  	}, nil
   112  }
   113  
   114  // MempoolTransaction fetches a single transaction in the mempool
   115  // NOTE: it is not implemented yet
   116  func (on OnlineNetwork) MempoolTransaction(ctx context.Context, request *types.MempoolTransactionRequest) (*types.MempoolTransactionResponse, *types.Error) {
   117  	tx, err := on.client.GetUnconfirmedTx(ctx, request.TransactionIdentifier.Hash)
   118  	if err != nil {
   119  		return nil, errors.ToRosetta(err)
   120  	}
   121  
   122  	return &types.MempoolTransactionResponse{
   123  		Transaction: tx,
   124  	}, nil
   125  }
   126  
   127  func (on OnlineNetwork) NetworkList(_ context.Context, _ *types.MetadataRequest) (*types.NetworkListResponse, *types.Error) {
   128  	return &types.NetworkListResponse{NetworkIdentifiers: []*types.NetworkIdentifier{on.network}}, nil
   129  }
   130  
   131  func (on OnlineNetwork) NetworkOptions(_ context.Context, _ *types.NetworkRequest) (*types.NetworkOptionsResponse, *types.Error) {
   132  	return on.networkOptions, nil
   133  }
   134  
   135  func (on OnlineNetwork) NetworkStatus(ctx context.Context, _ *types.NetworkRequest) (*types.NetworkStatusResponse, *types.Error) {
   136  	block, err := on.client.BlockByHeight(ctx, nil)
   137  	if err != nil {
   138  		return nil, errors.ToRosetta(err)
   139  	}
   140  
   141  	peers, err := on.client.Peers(ctx)
   142  	if err != nil {
   143  		return nil, errors.ToRosetta(err)
   144  	}
   145  
   146  	syncStatus, err := on.client.Status(ctx)
   147  	if err != nil {
   148  		return nil, errors.ToRosetta(err)
   149  	}
   150  
   151  	return &types.NetworkStatusResponse{
   152  		CurrentBlockIdentifier: block.Block,
   153  		CurrentBlockTimestamp:  block.MillisecondTimestamp,
   154  		GenesisBlockIdentifier: on.genesisBlockIdentifier,
   155  		OldestBlockIdentifier:  nil,
   156  		SyncStatus:             syncStatus,
   157  		Peers:                  peers,
   158  	}, nil
   159  }