Revert "Add and fix missing txn/staking txn rpc apis (#2343)" (#2369)

This reverts commit 84abf83065.
pull/2372/head
Rongjian Lan 5 years ago committed by GitHub
parent be917f79ee
commit b7a8c506eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      hmy/api_backend.go
  2. 7
      internal/hmyapi/apiv1/backend.go
  3. 251
      internal/hmyapi/apiv1/transactionpool.go
  4. 17
      internal/hmyapi/apiv1/util.go
  5. 7
      internal/hmyapi/apiv2/backend.go
  6. 355
      internal/hmyapi/apiv2/transactionpool.go
  7. 6
      internal/hmyapi/apiv2/types.go
  8. 17
      internal/hmyapi/apiv2/util.go
  9. 6
      internal/hmyapi/backend.go

@ -207,6 +207,7 @@ func (b *APIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscripti
} }
// GetPoolTransactions returns pool transactions. // GetPoolTransactions returns pool transactions.
// TODO: this is not implemented or verified yet for harmony.
func (b *APIBackend) GetPoolTransactions() (types.PoolTransactions, error) { func (b *APIBackend) GetPoolTransactions() (types.PoolTransactions, error) {
pending, err := b.hmy.txPool.Pending() pending, err := b.hmy.txPool.Pending()
if err != nil { if err != nil {

@ -49,20 +49,15 @@ type Backend interface {
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription
// TxPool API // TxPool API
SendTx(ctx context.Context, signedTx *types.Transaction) error SendTx(ctx context.Context, signedTx *types.Transaction) error
SendStakingTx(ctx context.Context, newStakingTx *staking.StakingTransaction) error
// GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) // GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error)
// Note that tx pool will contain both regular and staking txns together
GetPoolTransactions() (types.PoolTransactions, error) GetPoolTransactions() (types.PoolTransactions, error)
// GetPoolTransaction ... txHash can be either regular or staking txn hash
GetPoolTransaction(txHash common.Hash) types.PoolTransaction GetPoolTransaction(txHash common.Hash) types.PoolTransaction
GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error)
// Stats() (pending int, queued int) // Stats() (pending int, queued int)
// TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) // TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions)
SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
ChainConfig() *params.ChainConfig ChainConfig() *params.ChainConfig
CurrentBlock() *types.Block CurrentBlock() *types.Block
// Get balance // Get balance
@ -75,7 +70,7 @@ type Backend interface {
// retrieve the blockHash using txID and add blockHash to CxPool for resending // retrieve the blockHash using txID and add blockHash to CxPool for resending
ResendCx(ctx context.Context, txID common.Hash) (uint64, bool) ResendCx(ctx context.Context, txID common.Hash) (uint64, bool)
IsLeader() bool IsLeader() bool
SendStakingTx(ctx context.Context, newStakingTx *staking.StakingTransaction) error
GetElectedValidatorAddresses() []common.Address GetElectedValidatorAddresses() []common.Address
GetAllValidatorAddresses() []common.Address GetAllValidatorAddresses() []common.Address
GetValidatorInformation(addr common.Address) *staking.ValidatorWrapper GetValidatorInformation(addr common.Address) *staking.ValidatorWrapper

@ -42,10 +42,8 @@ func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransa
return &PublicTransactionPoolAPI{b, nonceLock} return &PublicTransactionPoolAPI{b, nonceLock}
} }
// GetTransactionsHistory returns the list of transactions hashes // GetTransactionsHistory returns the list of transactions hashes that involve a particular address.
// that involve a particular address. func (s *PublicTransactionPoolAPI) GetTransactionsHistory(ctx context.Context, args TxHistoryArgs) (map[string]interface{}, error) {
func (s *PublicTransactionPoolAPI) GetTransactionsHistory(
ctx context.Context, args TxHistoryArgs) (map[string]interface{}, error) {
address := args.Address address := args.Address
result := []common.Hash{} result := []common.Hash{}
var err error var err error
@ -62,58 +60,20 @@ func (s *PublicTransactionPoolAPI) GetTransactionsHistory(
if err != nil { if err != nil {
return nil, err return nil, err
} }
result = ReturnWithPagination(hashes, args.PageIndex, args.PageSize) result = ReturnWithPagination(hashes, args)
if !args.FullTx { if !args.FullTx {
return map[string]interface{}{"transactions": result}, nil return map[string]interface{}{"transactions": result}, nil
} }
txs := []*RPCTransaction{} txs := []*RPCTransaction{}
for _, hash := range result { for _, hash := range result {
tx := s.GetTransactionByHash(ctx, hash) tx := s.GetTransactionByHash(ctx, hash)
if tx != nil { txs = append(txs, tx)
txs = append(txs, tx)
}
} }
return map[string]interface{}{"transactions": txs}, nil return map[string]interface{}{"transactions": txs}, nil
} }
// GetStakingTransactionsHistory returns the list of staking transactions hashes // GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number.
// that involve a particular address. func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint {
func (s *PublicTransactionPoolAPI) GetStakingTransactionsHistory(
ctx context.Context, args TxHistoryArgs) (map[string]interface{}, error) {
address := args.Address
result := []common.Hash{}
var err error
if strings.HasPrefix(args.Address, "one1") {
address = args.Address
} else {
addr := internal_common.ParseAddr(args.Address)
address, err = internal_common.AddressToBech32(addr)
if err != nil {
return nil, err
}
}
hashes, err := s.b.GetTransactionsHistory(address, args.TxType, args.Order)
if err != nil {
return nil, err
}
result = ReturnWithPagination(hashes, args.PageIndex, args.PageSize)
if !args.FullTx {
return map[string]interface{}{"staking_transactions": result}, nil
}
txs := []*RPCStakingTransaction{}
for _, hash := range result {
tx := s.GetStakingTransactionByHash(ctx, hash)
if tx != nil {
txs = append(txs, tx)
}
}
return map[string]interface{}{"staking_transactions": txs}, nil
}
// GetBlockTransactionCountByNumber returns the number of transactions
// in the block with the given block number.
func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(
ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint {
if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
n := hexutil.Uint(len(block.Transactions())) n := hexutil.Uint(len(block.Transactions()))
return &n return &n
@ -121,21 +81,8 @@ func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(
return nil return nil
} }
// GetBlockStakingTransactionCountByNumber returns the number of staking transactions // GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash.
// in the block with the given block number. func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint {
func (s *PublicTransactionPoolAPI) GetBlockStakingTransactionCountByNumber(
ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint {
if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
n := hexutil.Uint(len(block.StakingTransactions()))
return &n
}
return nil
}
// GetBlockTransactionCountByHash returns the number of transactions
// in the block with the given hash.
func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(
ctx context.Context, blockHash common.Hash) *hexutil.Uint {
if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
n := hexutil.Uint(len(block.Transactions())) n := hexutil.Uint(len(block.Transactions()))
return &n return &n
@ -143,60 +90,24 @@ func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(
return nil return nil
} }
// GetBlockStakingTransactionCountByHash returns the number of staking transactions // GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index.
// in the block with the given hash. func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction {
func (s *PublicTransactionPoolAPI) GetBlockStakingTransactionCountByHash(
ctx context.Context, blockHash common.Hash) *hexutil.Uint {
if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
n := hexutil.Uint(len(block.StakingTransactions()))
return &n
}
return nil
}
// GetTransactionByBlockNumberAndIndex returns the transaction
// for the given block number and index.
func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(
ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction {
if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
return newRPCTransactionFromBlockIndex(block, uint64(index)) return newRPCTransactionFromBlockIndex(block, uint64(index))
} }
return nil return nil
} }
// GetStakingTransactionByBlockNumberAndIndex returns the staking transaction // GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index.
// for the given block number and index. func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction {
func (s *PublicTransactionPoolAPI) GetStakingTransactionByBlockNumberAndIndex(
ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCStakingTransaction {
if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
return newRPCStakingTransactionFromBlockIndex(block, uint64(index))
}
return nil
}
// GetTransactionByBlockHashAndIndex returns the transaction
// for the given block hash and index.
func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(
ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction {
if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
return newRPCTransactionFromBlockIndex(block, uint64(index)) return newRPCTransactionFromBlockIndex(block, uint64(index))
} }
return nil return nil
} }
// GetStakingTransactionByBlockHashAndIndex returns the staking transaction
// for the given block hash and index.
func (s *PublicTransactionPoolAPI) GetStakingTransactionByBlockHashAndIndex(
ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCStakingTransaction {
if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
return newRPCStakingTransactionFromBlockIndex(block, uint64(index))
}
return nil
}
// GetTransactionByHash returns the plain transaction for the given hash // GetTransactionByHash returns the plain transaction for the given hash
func (s *PublicTransactionPoolAPI) GetTransactionByHash( func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) *RPCTransaction {
ctx context.Context, hash common.Hash) *RPCTransaction {
// Try to return an already finalized transaction // Try to return an already finalized transaction
tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash) tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash)
block, _ := s.b.GetBlock(ctx, blockHash) block, _ := s.b.GetBlock(ctx, blockHash)
@ -211,8 +122,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionByHash(
} }
// GetStakingTransactionByHash returns the staking transaction for the given hash // GetStakingTransactionByHash returns the staking transaction for the given hash
func (s *PublicTransactionPoolAPI) GetStakingTransactionByHash( func (s *PublicTransactionPoolAPI) GetStakingTransactionByHash(ctx context.Context, hash common.Hash) *RPCStakingTransaction {
ctx context.Context, hash common.Hash) *RPCStakingTransaction {
// Try to return an already finalized transaction // Try to return an already finalized transaction
stx, blockHash, blockNumber, index := rawdb.ReadStakingTransaction(s.b.ChainDb(), hash) stx, blockHash, blockNumber, index := rawdb.ReadStakingTransaction(s.b.ChainDb(), hash)
block, _ := s.b.GetBlock(ctx, blockHash) block, _ := s.b.GetBlock(ctx, blockHash)
@ -226,12 +136,24 @@ func (s *PublicTransactionPoolAPI) GetStakingTransactionByHash(
return nil return nil
} }
// GetTransactionCount returns the number of transactions // GetStakingTransactionByBlockNumberAndIndex returns the transaction for the given block number and index.
// the given address has sent from genesis to the input block number func (s *PublicTransactionPoolAPI) GetStakingTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCStakingTransaction {
// NOTE: unlike other txn apis where staking vs. regular txns are separate, if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
// the transaction count here includes the count of both regular and staking txns return newRPCStakingTransactionFromBlockIndex(block, uint64(index))
func (s *PublicTransactionPoolAPI) GetTransactionCount( }
ctx context.Context, addr string, blockNr rpc.BlockNumber) (*hexutil.Uint64, error) { return nil
}
// GetStakingTransactionByBlockHashAndIndex returns the transaction for the given block hash and index.
func (s *PublicTransactionPoolAPI) GetStakingTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCStakingTransaction {
if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
return newRPCStakingTransactionFromBlockIndex(block, uint64(index))
}
return nil
}
// GetTransactionCount returns the number of transactions the given address has sent for the given block number
func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, addr string, blockNr rpc.BlockNumber) (*hexutil.Uint64, error) {
address := internal_common.ParseAddr(addr) address := internal_common.ParseAddr(addr)
// Ask transaction pool for the nonce which includes pending transactions // Ask transaction pool for the nonce which includes pending transactions
if blockNr == rpc.PendingBlockNumber { if blockNr == rpc.PendingBlockNumber {
@ -250,10 +172,9 @@ func (s *PublicTransactionPoolAPI) GetTransactionCount(
return (*hexutil.Uint64)(&nonce), state.Error() return (*hexutil.Uint64)(&nonce), state.Error()
} }
// SendTransaction creates a transaction for the given argument, // SendTransaction creates a transaction for the given argument, sign it and submit it to the
// sign it and submit it to the transaction pool. // transaction pool.
func (s *PublicTransactionPoolAPI) SendTransaction( func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) {
ctx context.Context, args SendTxArgs) (common.Hash, error) {
// Look up the wallet containing the requested signer // Look up the wallet containing the requested signer
account := accounts.Account{Address: args.From} account := accounts.Account{Address: args.From}
@ -263,8 +184,8 @@ func (s *PublicTransactionPoolAPI) SendTransaction(
} }
if args.Nonce == nil { if args.Nonce == nil {
// Hold the addresse's mutex around signing to prevent // Hold the addresse's mutex around signing to prevent concurrent assignment of
// concurrent assignment of the same nonce to multiple accounts. // the same nonce to multiple accounts.
s.nonceLock.LockAddr(args.From) s.nonceLock.LockAddr(args.From)
defer s.nonceLock.UnlockAddr(args.From) defer s.nonceLock.UnlockAddr(args.From)
} }
@ -283,11 +204,12 @@ func (s *PublicTransactionPoolAPI) SendTransaction(
return SubmitTransaction(ctx, s.b, signed) return SubmitTransaction(ctx, s.b, signed)
} }
// SendRawTransaction will add the signed transaction to the transaction pool. // SendRawStakingTransaction will add the signed transaction to the transaction pool.
// The sender is responsible for signing the transaction and using the correct nonce. // The sender is responsible for signing the transaction and using the correct nonce.
func (s *PublicTransactionPoolAPI) SendRawTransaction( func (s *PublicTransactionPoolAPI) SendRawStakingTransaction(
ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) { ctx context.Context, encodedTx hexutil.Bytes,
tx := new(types.Transaction) ) (common.Hash, error) {
tx := new(staking.StakingTransaction)
if err := rlp.DecodeBytes(encodedTx, tx); err != nil { if err := rlp.DecodeBytes(encodedTx, tx); err != nil {
return common.Hash{}, err return common.Hash{}, err
} }
@ -296,15 +218,13 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(
e := errors.Wrapf(errInvalidChainID, "current chain id:%s", c.String()) e := errors.Wrapf(errInvalidChainID, "current chain id:%s", c.String())
return common.Hash{}, e return common.Hash{}, e
} }
return SubmitTransaction(ctx, s.b, tx) return SubmitStakingTransaction(ctx, s.b, tx)
} }
// SendRawStakingTransaction will add the signed staking transaction to the transaction pool. // SendRawTransaction will add the signed transaction to the transaction pool.
// The sender is responsible for signing the transaction and using the correct nonce. // The sender is responsible for signing the transaction and using the correct nonce.
func (s *PublicTransactionPoolAPI) SendRawStakingTransaction( func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) {
ctx context.Context, encodedTx hexutil.Bytes, tx := new(types.Transaction)
) (common.Hash, error) {
tx := new(staking.StakingTransaction)
if err := rlp.DecodeBytes(encodedTx, tx); err != nil { if err := rlp.DecodeBytes(encodedTx, tx); err != nil {
return common.Hash{}, err return common.Hash{}, err
} }
@ -313,11 +233,10 @@ func (s *PublicTransactionPoolAPI) SendRawStakingTransaction(
e := errors.Wrapf(errInvalidChainID, "current chain id:%s", c.String()) e := errors.Wrapf(errInvalidChainID, "current chain id:%s", c.String())
return common.Hash{}, e return common.Hash{}, e
} }
return SubmitStakingTransaction(ctx, s.b, tx) return SubmitTransaction(ctx, s.b, tx)
} }
func (s *PublicTransactionPoolAPI) fillTransactionFields( func (s *PublicTransactionPoolAPI) fillTransactionFields(tx *types.Transaction, fields map[string]interface{}) error {
tx *types.Transaction, fields map[string]interface{}) error {
var err error var err error
fields["shardID"] = tx.ShardID() fields["shardID"] = tx.ShardID()
var signer types.Signer = types.FrontierSigner{} var signer types.Signer = types.FrontierSigner{}
@ -340,8 +259,7 @@ func (s *PublicTransactionPoolAPI) fillTransactionFields(
return nil return nil
} }
func (s *PublicTransactionPoolAPI) fillStakingTransactionFields( func (s *PublicTransactionPoolAPI) fillStakingTransactionFields(stx *staking.StakingTransaction, fields map[string]interface{}) error {
stx *staking.StakingTransaction, fields map[string]interface{}) error {
from, err := stx.SenderAddress() from, err := stx.SenderAddress()
if err != nil { if err != nil {
return err return err
@ -355,66 +273,7 @@ func (s *PublicTransactionPoolAPI) fillStakingTransactionFields(
} }
// GetTransactionReceipt returns the transaction receipt for the given transaction hash. // GetTransactionReceipt returns the transaction receipt for the given transaction hash.
func (s *PublicTransactionPoolAPI) GetTransactionReceipt( func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
var tx *types.Transaction
var stx *staking.StakingTransaction
var blockHash common.Hash
var blockNumber, index uint64
tx, blockHash, blockNumber, index = rawdb.ReadTransaction(s.b.ChainDb(), hash)
if tx == nil {
stx, blockHash, blockNumber, index = rawdb.ReadStakingTransaction(s.b.ChainDb(), hash)
if stx == nil {
return nil, nil
}
}
receipts, err := s.b.GetReceipts(ctx, blockHash)
if err != nil {
return nil, err
}
if len(receipts) <= int(index) {
return nil, nil
}
receipt := receipts[index]
fields := map[string]interface{}{
"blockHash": blockHash,
"blockNumber": hexutil.Uint64(blockNumber),
"transactionHash": hash,
"transactionIndex": hexutil.Uint64(index),
"gasUsed": hexutil.Uint64(receipt.GasUsed),
"cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed),
"contractAddress": nil,
"logs": receipt.Logs,
"logsBloom": receipt.Bloom,
}
if tx != nil {
if err = s.fillTransactionFields(tx, fields); err != nil {
return nil, err
}
} else { // stx not nil
if err = s.fillStakingTransactionFields(stx, fields); err != nil {
return nil, err
}
}
// Assign receipt status or post state.
if len(receipt.PostState) > 0 {
fields["root"] = hexutil.Bytes(receipt.PostState)
} else {
fields["status"] = hexutil.Uint(receipt.Status)
}
if receipt.Logs == nil {
fields["logs"] = [][]*types.Log{}
}
// If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation
if receipt.ContractAddress != (common.Address{}) {
fields["contractAddress"] = receipt.ContractAddress
}
return fields, nil
}
// GetStakingTransactionReceipt returns the staking transaction receipt for the given transaction hash.
func (s *PublicTransactionPoolAPI) GetStakingTransactionReceipt(
ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
var tx *types.Transaction var tx *types.Transaction
var stx *staking.StakingTransaction var stx *staking.StakingTransaction
var blockHash common.Hash var blockHash common.Hash
@ -518,17 +377,15 @@ func (s *PublicTransactionPoolAPI) GetCurrentStakingErrorSink() []staking.RPCTra
return s.b.GetCurrentStakingErrorSink() return s.b.GetCurrentStakingErrorSink()
} }
// GetCXReceiptByHash returns the transaction receipt for the given hash // GetCXReceiptByHash returns the transaction for the given hash
func (s *PublicTransactionPoolAPI) GetCXReceiptByHash( func (s *PublicTransactionPoolAPI) GetCXReceiptByHash(ctx context.Context, hash common.Hash) *RPCCXReceipt {
ctx context.Context, hash common.Hash) *RPCCXReceipt {
if cx, blockHash, blockNumber, _ := rawdb.ReadCXReceipt(s.b.ChainDb(), hash); cx != nil { if cx, blockHash, blockNumber, _ := rawdb.ReadCXReceipt(s.b.ChainDb(), hash); cx != nil {
return newRPCCXReceipt(cx, blockHash, blockNumber) return newRPCCXReceipt(cx, blockHash, blockNumber)
} }
return nil return nil
} }
// GetPendingCXReceipts returns the pending transaction receipts // GetPendingCXReceipts ..
func (s *PublicTransactionPoolAPI) GetPendingCXReceipts( func (s *PublicTransactionPoolAPI) GetPendingCXReceipts(ctx context.Context) []*types.CXReceiptsProof {
ctx context.Context) []*types.CXReceiptsProof {
return s.b.GetPendingCXReceipts() return s.b.GetPendingCXReceipts()
} }

@ -17,18 +17,19 @@ const (
) )
// ReturnWithPagination returns result with pagination (offset, page in TxHistoryArgs). // ReturnWithPagination returns result with pagination (offset, page in TxHistoryArgs).
func ReturnWithPagination(hashes []common.Hash, pageIndex uint32, pageSize uint32) []common.Hash { func ReturnWithPagination(hashes []common.Hash, args TxHistoryArgs) []common.Hash {
size := defaultPageSize pageSize := defaultPageSize
if pageSize > 0 { pageIndex := args.PageIndex
size = pageSize if args.PageSize > 0 {
pageSize = args.PageSize
} }
if uint64(size)*uint64(pageIndex) >= uint64(len(hashes)) { if uint64(pageSize)*uint64(pageIndex) >= uint64(len(hashes)) {
return make([]common.Hash, 0) return make([]common.Hash, 0)
} }
if uint64(size)*uint64(pageIndex)+uint64(size) > uint64(len(hashes)) { if uint64(pageSize)*uint64(pageIndex)+uint64(pageSize) > uint64(len(hashes)) {
return hashes[size*pageIndex:] return hashes[pageSize*pageIndex:]
} }
return hashes[size*pageIndex : size*pageIndex+size] return hashes[pageSize*pageIndex : pageSize*pageIndex+pageSize]
} }
// SubmitTransaction is a helper function that submits tx to txPool and logs a message. // SubmitTransaction is a helper function that submits tx to txPool and logs a message.

@ -49,20 +49,15 @@ type Backend interface {
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription
// TxPool API // TxPool API
SendTx(ctx context.Context, signedTx *types.Transaction) error SendTx(ctx context.Context, signedTx *types.Transaction) error
SendStakingTx(ctx context.Context, newStakingTx *staking.StakingTransaction) error
// GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) // GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error)
// Note that tx pool will contain both regular and staking txns together
GetPoolTransactions() (types.PoolTransactions, error) GetPoolTransactions() (types.PoolTransactions, error)
// GetPoolTransaction ... txHash can be either regular or staking txn hash
GetPoolTransaction(txHash common.Hash) types.PoolTransaction GetPoolTransaction(txHash common.Hash) types.PoolTransaction
GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error)
// Stats() (pending int, queued int) // Stats() (pending int, queued int)
// TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) // TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions)
SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
ChainConfig() *params.ChainConfig ChainConfig() *params.ChainConfig
CurrentBlock() *types.Block CurrentBlock() *types.Block
// Get balance // Get balance
@ -75,7 +70,7 @@ type Backend interface {
// retrieve the blockHash using txID and add blockHash to CxPool for resending // retrieve the blockHash using txID and add blockHash to CxPool for resending
ResendCx(ctx context.Context, txID common.Hash) (uint64, bool) ResendCx(ctx context.Context, txID common.Hash) (uint64, bool)
IsLeader() bool IsLeader() bool
SendStakingTx(ctx context.Context, newStakingTx *staking.StakingTransaction) error
GetElectedValidatorAddresses() []common.Address GetElectedValidatorAddresses() []common.Address
GetAllValidatorAddresses() []common.Address GetAllValidatorAddresses() []common.Address
GetValidatorInformation(addr common.Address) *staking.ValidatorWrapper GetValidatorInformation(addr common.Address) *staking.ValidatorWrapper

@ -42,10 +42,8 @@ func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransa
return &PublicTransactionPoolAPI{b, nonceLock} return &PublicTransactionPoolAPI{b, nonceLock}
} }
// GetTransactionsHistory returns the list of transactions hashes // GetTransactionsHistory returns the list of transactions hashes that involve a particular address.
// that involve a particular address. func (s *PublicTransactionPoolAPI) GetTransactionsHistory(ctx context.Context, args TxHistoryArgs) (map[string]interface{}, error) {
func (s *PublicTransactionPoolAPI) GetTransactionsHistory(
ctx context.Context, args TxHistoryArgs) (map[string]interface{}, error) {
address := args.Address address := args.Address
result := []common.Hash{} result := []common.Hash{}
var err error var err error
@ -62,141 +60,52 @@ func (s *PublicTransactionPoolAPI) GetTransactionsHistory(
if err != nil { if err != nil {
return nil, err return nil, err
} }
result = ReturnWithPagination(hashes, args.PageIndex, args.PageSize) result = ReturnWithPagination(hashes, args)
if !args.FullTx { if !args.FullTx {
return map[string]interface{}{"transactions": result}, nil return map[string]interface{}{"transactions": result}, nil
} }
txs := []*RPCTransaction{} txs := []*RPCTransaction{}
for _, hash := range result { for _, hash := range result {
tx := s.GetTransactionByHash(ctx, hash) tx := s.GetTransactionByHash(ctx, hash)
if tx != nil { txs = append(txs, tx)
txs = append(txs, tx)
}
} }
return map[string]interface{}{"transactions": txs}, nil return map[string]interface{}{"transactions": txs}, nil
} }
// GetStakingTransactionsHistory returns the list of staking transactions hashes // GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number.
// that involve a particular address. func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr uint64) int {
func (s *PublicTransactionPoolAPI) GetStakingTransactionsHistory( if block, _ := s.b.BlockByNumber(ctx, rpc.BlockNumber(blockNr)); block != nil {
ctx context.Context, args TxHistoryArgs) (map[string]interface{}, error) { return len(block.Transactions())
address := args.Address
result := []common.Hash{}
var err error
if strings.HasPrefix(args.Address, "one1") {
address = args.Address
} else {
addr := internal_common.ParseAddr(args.Address)
address, err = internal_common.AddressToBech32(addr)
if err != nil {
return nil, err
}
}
hashes, err := s.b.GetTransactionsHistory(address, args.TxType, args.Order)
if err != nil {
return nil, err
}
result = ReturnWithPagination(hashes, args.PageIndex, args.PageSize)
if !args.FullTx {
return map[string]interface{}{"staking_transactions": result}, nil
}
txs := []*RPCStakingTransaction{}
for _, hash := range result {
tx := s.GetStakingTransactionByHash(ctx, hash)
if tx != nil {
txs = append(txs, tx)
}
}
return map[string]interface{}{"staking_transactions": txs}, nil
}
// GetBlockTransactionCountByNumber returns the number of transactions
// in the block with the given block number.
func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(
ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint {
if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
n := hexutil.Uint(len(block.Transactions()))
return &n
}
return nil
}
// GetBlockStakingTransactionCountByNumber returns the number of staking transactions
// in the block with the given block number.
func (s *PublicTransactionPoolAPI) GetBlockStakingTransactionCountByNumber(
ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint {
if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
n := hexutil.Uint(len(block.StakingTransactions()))
return &n
}
return nil
}
// GetBlockTransactionCountByHash returns the number of transactions
// in the block with the given hash.
func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(
ctx context.Context, blockHash common.Hash) *hexutil.Uint {
if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
n := hexutil.Uint(len(block.Transactions()))
return &n
} }
return nil return 0
} }
// GetBlockStakingTransactionCountByHash returns the number of staking transactions // GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash.
// in the block with the given hash. func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) int {
func (s *PublicTransactionPoolAPI) GetBlockStakingTransactionCountByHash(
ctx context.Context, blockHash common.Hash) *hexutil.Uint {
if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
n := hexutil.Uint(len(block.StakingTransactions())) return len(block.Transactions())
return &n
}
return nil
}
// GetTransactionByBlockNumberAndIndex returns the transaction
// for the given block number and index.
func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(
ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction {
if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
return newRPCTransactionFromBlockIndex(block, uint64(index))
}
return nil
}
// GetStakingTransactionByBlockNumberAndIndex returns the staking transaction
// for the given block number and index.
func (s *PublicTransactionPoolAPI) GetStakingTransactionByBlockNumberAndIndex(
ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCStakingTransaction {
if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
return newRPCStakingTransactionFromBlockIndex(block, uint64(index))
} }
return nil return 0
} }
// GetTransactionByBlockHashAndIndex returns the transaction // GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index.
// for the given block hash and index. func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr uint64, index uint64) *RPCTransaction {
func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex( if block, _ := s.b.BlockByNumber(ctx, rpc.BlockNumber(blockNr)); block != nil {
ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction { return newRPCTransactionFromBlockIndex(block, index)
if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
return newRPCTransactionFromBlockIndex(block, uint64(index))
} }
return nil return nil
} }
// GetStakingTransactionByBlockHashAndIndex returns the staking transaction // GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index.
// for the given block hash and index. func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index uint64) *RPCTransaction {
func (s *PublicTransactionPoolAPI) GetStakingTransactionByBlockHashAndIndex(
ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCStakingTransaction {
if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
return newRPCStakingTransactionFromBlockIndex(block, uint64(index)) return newRPCTransactionFromBlockIndex(block, index)
} }
return nil return nil
} }
// GetTransactionByHash returns the plain transaction for the given hash // GetTransactionByHash returns the transaction for the given hash
func (s *PublicTransactionPoolAPI) GetTransactionByHash( func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) *RPCTransaction {
ctx context.Context, hash common.Hash) *RPCTransaction {
// Try to return an already finalized transaction // Try to return an already finalized transaction
tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash) tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash)
block, _ := s.b.GetBlock(ctx, blockHash) block, _ := s.b.GetBlock(ctx, blockHash)
@ -210,9 +119,8 @@ func (s *PublicTransactionPoolAPI) GetTransactionByHash(
return nil return nil
} }
// GetStakingTransactionByHash returns the staking transaction for the given hash // GetStakingTransactionByHash returns the transaction for the given hash
func (s *PublicTransactionPoolAPI) GetStakingTransactionByHash( func (s *PublicTransactionPoolAPI) GetStakingTransactionByHash(ctx context.Context, hash common.Hash) *RPCStakingTransaction {
ctx context.Context, hash common.Hash) *RPCStakingTransaction {
// Try to return an already finalized transaction // Try to return an already finalized transaction
stx, blockHash, blockNumber, index := rawdb.ReadStakingTransaction(s.b.ChainDb(), hash) stx, blockHash, blockNumber, index := rawdb.ReadStakingTransaction(s.b.ChainDb(), hash)
block, _ := s.b.GetBlock(ctx, blockHash) block, _ := s.b.GetBlock(ctx, blockHash)
@ -226,34 +134,45 @@ func (s *PublicTransactionPoolAPI) GetStakingTransactionByHash(
return nil return nil
} }
// GetTransactionCount returns the number of transactions // GetStakingTransactionByBlockNumberAndIndex returns the transaction for the given block number and index.
// the given address has sent from genesis to the input block number func (s *PublicTransactionPoolAPI) GetStakingTransactionByBlockNumberAndIndex(ctx context.Context, blockNr uint64, index uint64) *RPCStakingTransaction {
// NOTE: unlike other txn apis where staking vs. regular txns are separate, if block, _ := s.b.BlockByNumber(ctx, rpc.BlockNumber(blockNr)); block != nil {
// the transaction count here includes the count of both regular and staking txns return newRPCStakingTransactionFromBlockIndex(block, index)
func (s *PublicTransactionPoolAPI) GetTransactionCount( }
ctx context.Context, addr string, blockNr rpc.BlockNumber) (*hexutil.Uint64, error) { return nil
}
// GetStakingTransactionByBlockHashAndIndex returns the transaction for the given block hash and index.
func (s *PublicTransactionPoolAPI) GetStakingTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index uint64) *RPCStakingTransaction {
if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
return newRPCStakingTransactionFromBlockIndex(block, index)
}
return nil
}
// GetTransactionCount returns the number of transactions the given address has sent for the given block number
func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, addr string, blockNr uint64) (uint64, error) {
address := internal_common.ParseAddr(addr) address := internal_common.ParseAddr(addr)
// Ask transaction pool for the nonce which includes pending transactions // Ask transaction pool for the nonce which includes pending transactions
if blockNr == rpc.PendingBlockNumber { if rpc.BlockNumber(blockNr) == rpc.PendingBlockNumber {
nonce, err := s.b.GetPoolNonce(ctx, address) nonce, err := s.b.GetPoolNonce(ctx, address)
if err != nil { if err != nil {
return nil, err return 0, err
} }
return (*hexutil.Uint64)(&nonce), nil return nonce, nil
} }
// Resolve block number and use its state to ask for the nonce // Resolve block number and use its state to ask for the nonce
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) state, _, err := s.b.StateAndHeaderByNumber(ctx, rpc.BlockNumber(blockNr))
if state == nil || err != nil { if state == nil || err != nil {
return nil, err return 0, err
} }
nonce := state.GetNonce(address) nonce := state.GetNonce(address)
return (*hexutil.Uint64)(&nonce), state.Error() return nonce, state.Error()
} }
// SendTransaction creates a transaction for the given argument, // SendTransaction creates a transaction for the given argument, sign it and submit it to the
// sign it and submit it to the transaction pool. // transaction pool.
func (s *PublicTransactionPoolAPI) SendTransaction( func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) {
ctx context.Context, args SendTxArgs) (common.Hash, error) {
// Look up the wallet containing the requested signer // Look up the wallet containing the requested signer
account := accounts.Account{Address: args.From} account := accounts.Account{Address: args.From}
@ -263,8 +182,8 @@ func (s *PublicTransactionPoolAPI) SendTransaction(
} }
if args.Nonce == nil { if args.Nonce == nil {
// Hold the addresse's mutex around signing to prevent // Hold the addresse's mutex around signing to prevent concurrent assignment of
// concurrent assignment of the same nonce to multiple accounts. // the same nonce to multiple accounts.
s.nonceLock.LockAddr(args.From) s.nonceLock.LockAddr(args.From)
defer s.nonceLock.UnlockAddr(args.From) defer s.nonceLock.UnlockAddr(args.From)
} }
@ -283,11 +202,12 @@ func (s *PublicTransactionPoolAPI) SendTransaction(
return SubmitTransaction(ctx, s.b, signed) return SubmitTransaction(ctx, s.b, signed)
} }
// SendRawTransaction will add the signed transaction to the transaction pool. // SendRawStakingTransaction will add the signed transaction to the transaction pool.
// The sender is responsible for signing the transaction and using the correct nonce. // The sender is responsible for signing the transaction and using the correct nonce.
func (s *PublicTransactionPoolAPI) SendRawTransaction( func (s *PublicTransactionPoolAPI) SendRawStakingTransaction(
ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) { ctx context.Context, encodedTx hexutil.Bytes,
tx := new(types.Transaction) ) (common.Hash, error) {
tx := new(staking.StakingTransaction)
if err := rlp.DecodeBytes(encodedTx, tx); err != nil { if err := rlp.DecodeBytes(encodedTx, tx); err != nil {
return common.Hash{}, err return common.Hash{}, err
} }
@ -296,15 +216,13 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(
e := errors.Wrapf(errInvalidChainID, "current chain id:%s", c.String()) e := errors.Wrapf(errInvalidChainID, "current chain id:%s", c.String())
return common.Hash{}, e return common.Hash{}, e
} }
return SubmitTransaction(ctx, s.b, tx) return SubmitStakingTransaction(ctx, s.b, tx)
} }
// SendRawStakingTransaction will add the signed staking transaction to the transaction pool. // SendRawTransaction will add the signed transaction to the transaction pool.
// The sender is responsible for signing the transaction and using the correct nonce. // The sender is responsible for signing the transaction and using the correct nonce.
func (s *PublicTransactionPoolAPI) SendRawStakingTransaction( func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) {
ctx context.Context, encodedTx hexutil.Bytes, tx := new(types.Transaction)
) (common.Hash, error) {
tx := new(staking.StakingTransaction)
if err := rlp.DecodeBytes(encodedTx, tx); err != nil { if err := rlp.DecodeBytes(encodedTx, tx); err != nil {
return common.Hash{}, err return common.Hash{}, err
} }
@ -313,11 +231,10 @@ func (s *PublicTransactionPoolAPI) SendRawStakingTransaction(
e := errors.Wrapf(errInvalidChainID, "current chain id:%s", c.String()) e := errors.Wrapf(errInvalidChainID, "current chain id:%s", c.String())
return common.Hash{}, e return common.Hash{}, e
} }
return SubmitStakingTransaction(ctx, s.b, tx) return SubmitTransaction(ctx, s.b, tx)
} }
func (s *PublicTransactionPoolAPI) fillTransactionFields( func (s *PublicTransactionPoolAPI) fillTransactionFields(tx *types.Transaction, fields map[string]interface{}) error {
tx *types.Transaction, fields map[string]interface{}) error {
var err error var err error
fields["shardID"] = tx.ShardID() fields["shardID"] = tx.ShardID()
var signer types.Signer = types.FrontierSigner{} var signer types.Signer = types.FrontierSigner{}
@ -340,8 +257,7 @@ func (s *PublicTransactionPoolAPI) fillTransactionFields(
return nil return nil
} }
func (s *PublicTransactionPoolAPI) fillStakingTransactionFields( func (s *PublicTransactionPoolAPI) fillStakingTransactionFields(stx *staking.StakingTransaction, fields map[string]interface{}) error {
stx *staking.StakingTransaction, fields map[string]interface{}) error {
from, err := stx.SenderAddress() from, err := stx.SenderAddress()
if err != nil { if err != nil {
return err return err
@ -355,8 +271,7 @@ func (s *PublicTransactionPoolAPI) fillStakingTransactionFields(
} }
// GetTransactionReceipt returns the transaction receipt for the given transaction hash. // GetTransactionReceipt returns the transaction receipt for the given transaction hash.
func (s *PublicTransactionPoolAPI) GetTransactionReceipt( func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
var tx *types.Transaction var tx *types.Transaction
var stx *staking.StakingTransaction var stx *staking.StakingTransaction
var blockHash common.Hash var blockHash common.Hash
@ -378,11 +293,11 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(
receipt := receipts[index] receipt := receipts[index]
fields := map[string]interface{}{ fields := map[string]interface{}{
"blockHash": blockHash, "blockHash": blockHash,
"blockNumber": hexutil.Uint64(blockNumber), "blockNumber": blockNumber,
"transactionHash": hash, "transactionHash": hash,
"transactionIndex": hexutil.Uint64(index), "transactionIndex": index,
"gasUsed": hexutil.Uint64(receipt.GasUsed), "gasUsed": receipt.GasUsed,
"cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), "cumulativeGasUsed": receipt.CumulativeGasUsed,
"contractAddress": nil, "contractAddress": nil,
"logs": receipt.Logs, "logs": receipt.Logs,
"logsBloom": receipt.Bloom, "logsBloom": receipt.Bloom,
@ -400,65 +315,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(
if len(receipt.PostState) > 0 { if len(receipt.PostState) > 0 {
fields["root"] = hexutil.Bytes(receipt.PostState) fields["root"] = hexutil.Bytes(receipt.PostState)
} else { } else {
fields["status"] = hexutil.Uint(receipt.Status) fields["status"] = receipt.Status
}
if receipt.Logs == nil {
fields["logs"] = [][]*types.Log{}
}
// If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation
if receipt.ContractAddress != (common.Address{}) {
fields["contractAddress"] = receipt.ContractAddress
}
return fields, nil
}
// GetStakingTransactionReceipt returns the staking transaction receipt for the given transaction hash.
func (s *PublicTransactionPoolAPI) GetStakingTransactionReceipt(
ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
var tx *types.Transaction
var stx *staking.StakingTransaction
var blockHash common.Hash
var blockNumber, index uint64
tx, blockHash, blockNumber, index = rawdb.ReadTransaction(s.b.ChainDb(), hash)
if tx == nil {
stx, blockHash, blockNumber, index = rawdb.ReadStakingTransaction(s.b.ChainDb(), hash)
if stx == nil {
return nil, nil
}
}
receipts, err := s.b.GetReceipts(ctx, blockHash)
if err != nil {
return nil, err
}
if len(receipts) <= int(index) {
return nil, nil
}
receipt := receipts[index]
fields := map[string]interface{}{
"blockHash": blockHash,
"blockNumber": hexutil.Uint64(blockNumber),
"transactionHash": hash,
"transactionIndex": hexutil.Uint64(index),
"gasUsed": hexutil.Uint64(receipt.GasUsed),
"cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed),
"contractAddress": nil,
"logs": receipt.Logs,
"logsBloom": receipt.Bloom,
}
if tx != nil {
if err = s.fillTransactionFields(tx, fields); err != nil {
return nil, err
}
} else { // stx not nil
if err = s.fillStakingTransactionFields(stx, fields); err != nil {
return nil, err
}
}
// Assign receipt status or post state.
if len(receipt.PostState) > 0 {
fields["root"] = hexutil.Bytes(receipt.PostState)
} else {
fields["status"] = hexutil.Uint(receipt.Status)
} }
if receipt.Logs == nil { if receipt.Logs == nil {
fields["logs"] = [][]*types.Log{} fields["logs"] = [][]*types.Log{}
@ -471,38 +328,66 @@ func (s *PublicTransactionPoolAPI) GetStakingTransactionReceipt(
} }
// PendingTransactions returns the plain transactions that are in the transaction pool // PendingTransactions returns the plain transactions that are in the transaction pool
// and have a from address that is one of the accounts this node manages.
func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, error) { func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, error) {
pending, err := s.b.GetPoolTransactions() pending, err := s.b.GetPoolTransactions()
if err != nil { if err != nil {
return nil, err return nil, err
} }
transactions := make([]*RPCTransaction, len(pending)) managedAccounts := make(map[common.Address]struct{})
for i := range pending { for _, wallet := range s.b.AccountManager().Wallets() {
if plainTx, ok := pending[i].(*types.Transaction); ok { for _, account := range wallet.Accounts() {
transactions[i] = newRPCPendingTransaction(plainTx) managedAccounts[account.Address] = struct{}{}
} else if _, ok := pending[i].(*staking.StakingTransaction); ok { }
continue // Do not return staking transactions here. }
} else { transactions := make([]*RPCTransaction, 0, len(pending))
return nil, types.ErrUnknownPoolTxType for _, tx := range pending {
var signer types.Signer = types.HomesteadSigner{}
if tx.Protected() {
signer = types.NewEIP155Signer(tx.ChainID())
}
from, _ := types.PoolTransactionSender(signer, tx)
if _, exists := managedAccounts[from]; exists {
if plainTx, ok := tx.(*types.Transaction); ok {
transactions = append(transactions, newRPCPendingTransaction(plainTx))
} else if _, ok := tx.(*staking.StakingTransaction); ok {
continue // Do not return staking transactions here
} else {
return nil, types.ErrUnknownPoolTxType
}
} }
} }
return transactions, nil return transactions, nil
} }
// PendingStakingTransactions returns the staking transactions that are in the transaction pool // PendingStakingTransactions returns the staking transactions that are in the transaction pool
// and have a from address that is one of the accounts this node manages.
func (s *PublicTransactionPoolAPI) PendingStakingTransactions() ([]*RPCStakingTransaction, error) { func (s *PublicTransactionPoolAPI) PendingStakingTransactions() ([]*RPCStakingTransaction, error) {
pending, err := s.b.GetPoolTransactions() pending, err := s.b.GetPoolTransactions()
if err != nil { if err != nil {
return nil, err return nil, err
} }
transactions := make([]*RPCStakingTransaction, len(pending)) managedAccounts := make(map[common.Address]struct{})
for i := range pending { for _, wallet := range s.b.AccountManager().Wallets() {
if _, ok := pending[i].(*types.Transaction); ok { for _, account := range wallet.Accounts() {
continue // Do not return plain transactions here managedAccounts[account.Address] = struct{}{}
} else if stakingTx, ok := pending[i].(*staking.StakingTransaction); ok { }
transactions[i] = newRPCPendingStakingTransaction(stakingTx) }
} else { transactions := make([]*RPCStakingTransaction, 0, len(pending))
return nil, types.ErrUnknownPoolTxType for _, tx := range pending {
var signer types.Signer = types.HomesteadSigner{}
if tx.Protected() {
signer = types.NewEIP155Signer(tx.ChainID())
}
from, _ := types.PoolTransactionSender(signer, tx)
if _, exists := managedAccounts[from]; exists {
if _, ok := tx.(*types.Transaction); ok {
continue // Do not return plain transactions here
} else if stakingTx, ok := tx.(*staking.StakingTransaction); ok {
transactions = append(transactions, newRPCPendingStakingTransaction(stakingTx))
} else {
return nil, types.ErrUnknownPoolTxType
}
} }
} }
return transactions, nil return transactions, nil
@ -518,17 +403,15 @@ func (s *PublicTransactionPoolAPI) GetCurrentStakingErrorSink() []staking.RPCTra
return s.b.GetCurrentStakingErrorSink() return s.b.GetCurrentStakingErrorSink()
} }
// GetCXReceiptByHash returns the transaction receipt for the given hash // GetCXReceiptByHash returns the transaction for the given hash
func (s *PublicTransactionPoolAPI) GetCXReceiptByHash( func (s *PublicTransactionPoolAPI) GetCXReceiptByHash(ctx context.Context, hash common.Hash) *RPCCXReceipt {
ctx context.Context, hash common.Hash) *RPCCXReceipt {
if cx, blockHash, blockNumber, _ := rawdb.ReadCXReceipt(s.b.ChainDb(), hash); cx != nil { if cx, blockHash, blockNumber, _ := rawdb.ReadCXReceipt(s.b.ChainDb(), hash); cx != nil {
return newRPCCXReceipt(cx, blockHash, blockNumber) return newRPCCXReceipt(cx, blockHash, blockNumber)
} }
return nil return nil
} }
// GetPendingCXReceipts returns the pending transaction receipts // GetPendingCXReceipts ..
func (s *PublicTransactionPoolAPI) GetPendingCXReceipts( func (s *PublicTransactionPoolAPI) GetPendingCXReceipts(ctx context.Context) []*types.CXReceiptsProof {
ctx context.Context) []*types.CXReceiptsProof {
return s.b.GetPendingCXReceipts() return s.b.GetPendingCXReceipts()
} }

@ -204,7 +204,7 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber
return result return result
} }
// newRPCStakingTransaction returns a staking transaction that will serialize to the RPC // newRPCStakingTransaction returns a transaction that will serialize to the RPC
// representation, with the given location metadata set (if available). // representation, with the given location metadata set (if available).
func newRPCStakingTransaction(tx *types2.StakingTransaction, blockHash common.Hash, blockNumber uint64, timestamp uint64, index uint64) *RPCStakingTransaction { func newRPCStakingTransaction(tx *types2.StakingTransaction, blockHash common.Hash, blockNumber uint64, timestamp uint64, index uint64) *RPCStakingTransaction {
from, _ := tx.SenderAddress() from, _ := tx.SenderAddress()
@ -452,7 +452,7 @@ func newRPCTransactionFromBlockIndex(b *types.Block, index uint64) *RPCTransacti
return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), b.Time().Uint64(), index) return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), b.Time().Uint64(), index)
} }
// newRPCStakingTransactionFromBlockHash returns a staking transaction that will serialize to the RPC representation. // newRPCStakingTransactionFromBlockHash returns a transaction that will serialize to the RPC representation.
func newRPCStakingTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCStakingTransaction { func newRPCStakingTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCStakingTransaction {
for idx, tx := range b.StakingTransactions() { for idx, tx := range b.StakingTransactions() {
if tx.Hash() == hash { if tx.Hash() == hash {
@ -462,7 +462,7 @@ func newRPCStakingTransactionFromBlockHash(b *types.Block, hash common.Hash) *RP
return nil return nil
} }
// newRPCStakingTransactionFromBlockIndex returns a staking transaction that will serialize to the RPC representation. // newRPCStakingTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation.
func newRPCStakingTransactionFromBlockIndex(b *types.Block, index uint64) *RPCStakingTransaction { func newRPCStakingTransactionFromBlockIndex(b *types.Block, index uint64) *RPCStakingTransaction {
txs := b.StakingTransactions() txs := b.StakingTransactions()
if index >= uint64(len(txs)) { if index >= uint64(len(txs)) {

@ -17,18 +17,19 @@ const (
) )
// ReturnWithPagination returns result with pagination (offset, page in TxHistoryArgs). // ReturnWithPagination returns result with pagination (offset, page in TxHistoryArgs).
func ReturnWithPagination(hashes []common.Hash, pageIndex uint32, pageSize uint32) []common.Hash { func ReturnWithPagination(hashes []common.Hash, args TxHistoryArgs) []common.Hash {
size := defaultPageSize pageSize := defaultPageSize
if pageSize > 0 { pageIndex := args.PageIndex
size = pageSize if args.PageSize > 0 {
pageSize = args.PageSize
} }
if uint64(size)*uint64(pageIndex) >= uint64(len(hashes)) { if uint64(pageSize)*uint64(pageIndex) >= uint64(len(hashes)) {
return make([]common.Hash, 0) return make([]common.Hash, 0)
} }
if uint64(size)*uint64(pageIndex)+uint64(size) > uint64(len(hashes)) { if uint64(pageSize)*uint64(pageIndex)+uint64(pageSize) > uint64(len(hashes)) {
return hashes[size*pageIndex:] return hashes[pageSize*pageIndex:]
} }
return hashes[size*pageIndex : size*pageIndex+size] return hashes[pageSize*pageIndex : pageSize*pageIndex+pageSize]
} }
// SubmitTransaction is a helper function that submits tx to txPool and logs a message. // SubmitTransaction is a helper function that submits tx to txPool and logs a message.

@ -51,10 +51,8 @@ type Backend interface {
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription
// TxPool API // TxPool API
SendTx(ctx context.Context, signedTx *types.Transaction) error SendTx(ctx context.Context, signedTx *types.Transaction) error
SendStakingTx(ctx context.Context, newStakingTx *staking.StakingTransaction) error
// GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) // GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error)
GetPoolTransactions() (types.PoolTransactions, error) GetPoolTransactions() (types.PoolTransactions, error)
GetPoolTransaction(txHash common.Hash) types.PoolTransaction GetPoolTransaction(txHash common.Hash) types.PoolTransaction
@ -62,7 +60,6 @@ type Backend interface {
// Stats() (pending int, queued int) // Stats() (pending int, queued int)
// TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) // TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions)
SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
ChainConfig() *params.ChainConfig ChainConfig() *params.ChainConfig
CurrentBlock() *types.Block CurrentBlock() *types.Block
// Get balance // Get balance
@ -75,8 +72,7 @@ type Backend interface {
// retrieve the blockHash using txID and add blockHash to CxPool for resending // retrieve the blockHash using txID and add blockHash to CxPool for resending
ResendCx(ctx context.Context, txID common.Hash) (uint64, bool) ResendCx(ctx context.Context, txID common.Hash) (uint64, bool)
IsLeader() bool IsLeader() bool
SendStakingTx(ctx context.Context, newStakingTx *staking.StakingTransaction) error
// Staking info query apis
GetElectedValidatorAddresses() []common.Address GetElectedValidatorAddresses() []common.Address
GetAllValidatorAddresses() []common.Address GetAllValidatorAddresses() []common.Address
GetValidatorInformation(addr common.Address) *staking.ValidatorWrapper GetValidatorInformation(addr common.Address) *staking.ValidatorWrapper

Loading…
Cancel
Save