|
|
@ -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() |
|
|
|
} |
|
|
|
} |
|
|
|