forked from cerc-io/plugeth
Merge pull request #2098 from karalabe/rpc-txpool-queue-inspection
core, eth, rpc/api: rpc method to inspect the txpool queue
This commit is contained in:
commit
6005dcef5b
@ -169,6 +169,36 @@ func (pool *TxPool) Stats() (pending int, queued int) {
|
||||
return
|
||||
}
|
||||
|
||||
// Content retrieves the data content of the transaction pool, returning all the
|
||||
// pending as well as queued transactions, grouped by account and nonce.
|
||||
func (pool *TxPool) Content() (map[common.Address]map[uint64][]*types.Transaction, map[common.Address]map[uint64][]*types.Transaction) {
|
||||
pool.mu.RLock()
|
||||
defer pool.mu.RUnlock()
|
||||
|
||||
// Retrieve all the pending transactions and sort by account and by nonce
|
||||
pending := make(map[common.Address]map[uint64][]*types.Transaction)
|
||||
for _, tx := range pool.pending {
|
||||
account, _ := tx.From()
|
||||
|
||||
owned, ok := pending[account]
|
||||
if !ok {
|
||||
owned = make(map[uint64][]*types.Transaction)
|
||||
pending[account] = owned
|
||||
}
|
||||
owned[tx.Nonce()] = append(owned[tx.Nonce()], tx)
|
||||
}
|
||||
// Retrieve all the queued transactions and sort by account and by nonce
|
||||
queued := make(map[common.Address]map[uint64][]*types.Transaction)
|
||||
for account, txs := range pool.queue {
|
||||
owned := make(map[uint64][]*types.Transaction)
|
||||
for _, tx := range txs {
|
||||
owned[tx.Nonce()] = append(owned[tx.Nonce()], tx)
|
||||
}
|
||||
queued[account] = owned
|
||||
}
|
||||
return pending, queued
|
||||
}
|
||||
|
||||
// SetLocal marks a transaction as local, skipping gas price
|
||||
// check against local miner minimum in the future
|
||||
func (pool *TxPool) SetLocal(tx *types.Transaction) {
|
||||
|
74
eth/api.go
74
eth/api.go
@ -227,6 +227,39 @@ func NewPublicTxPoolAPI(e *Ethereum) *PublicTxPoolAPI {
|
||||
return &PublicTxPoolAPI{e}
|
||||
}
|
||||
|
||||
// Content returns the transactions contained within the transaction pool.
|
||||
func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string][]*RPCTransaction {
|
||||
content := map[string]map[string]map[string][]*RPCTransaction{
|
||||
"pending": make(map[string]map[string][]*RPCTransaction),
|
||||
"queued": make(map[string]map[string][]*RPCTransaction),
|
||||
}
|
||||
pending, queue := s.e.TxPool().Content()
|
||||
|
||||
// Flatten the pending transactions
|
||||
for account, batches := range pending {
|
||||
dump := make(map[string][]*RPCTransaction)
|
||||
for nonce, txs := range batches {
|
||||
nonce := fmt.Sprintf("%d", nonce)
|
||||
for _, tx := range txs {
|
||||
dump[nonce] = append(dump[nonce], newRPCPendingTransaction(tx))
|
||||
}
|
||||
}
|
||||
content["pending"][account.Hex()] = dump
|
||||
}
|
||||
// Flatten the queued transactions
|
||||
for account, batches := range queue {
|
||||
dump := make(map[string][]*RPCTransaction)
|
||||
for nonce, txs := range batches {
|
||||
nonce := fmt.Sprintf("%d", nonce)
|
||||
for _, tx := range txs {
|
||||
dump[nonce] = append(dump[nonce], newRPCPendingTransaction(tx))
|
||||
}
|
||||
}
|
||||
content["queued"][account.Hex()] = dump
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
// Status returns the number of pending and queued transaction in the pool.
|
||||
func (s *PublicTxPoolAPI) Status() map[string]*rpc.HexNumber {
|
||||
pending, queue := s.e.TxPool().Stats()
|
||||
@ -236,6 +269,47 @@ func (s *PublicTxPoolAPI) Status() map[string]*rpc.HexNumber {
|
||||
}
|
||||
}
|
||||
|
||||
// Inspect retrieves the content of the transaction pool and flattens it into an
|
||||
// easily inspectable list.
|
||||
func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string][]string {
|
||||
content := map[string]map[string]map[string][]string{
|
||||
"pending": make(map[string]map[string][]string),
|
||||
"queued": make(map[string]map[string][]string),
|
||||
}
|
||||
pending, queue := s.e.TxPool().Content()
|
||||
|
||||
// Define a formatter to flatten a transaction into a string
|
||||
var format = func(tx *types.Transaction) string {
|
||||
if to := tx.To(); to != nil {
|
||||
return fmt.Sprintf("%s: %v wei + %v × %v gas", tx.To().Hex(), tx.Value(), tx.Gas(), tx.GasPrice())
|
||||
}
|
||||
return fmt.Sprintf("contract creation: %v wei + %v × %v gas", tx.Value(), tx.Gas(), tx.GasPrice())
|
||||
}
|
||||
// Flatten the pending transactions
|
||||
for account, batches := range pending {
|
||||
dump := make(map[string][]string)
|
||||
for nonce, txs := range batches {
|
||||
nonce := fmt.Sprintf("%d", nonce)
|
||||
for _, tx := range txs {
|
||||
dump[nonce] = append(dump[nonce], format(tx))
|
||||
}
|
||||
}
|
||||
content["pending"][account.Hex()] = dump
|
||||
}
|
||||
// Flatten the queued transactions
|
||||
for account, batches := range queue {
|
||||
dump := make(map[string][]string)
|
||||
for nonce, txs := range batches {
|
||||
nonce := fmt.Sprintf("%d", nonce)
|
||||
for _, tx := range txs {
|
||||
dump[nonce] = append(dump[nonce], format(tx))
|
||||
}
|
||||
}
|
||||
content["queued"][account.Hex()] = dump
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
// PublicAccountAPI provides an API to access accounts managed by this node.
|
||||
// It offers only methods that can retrieve accounts.
|
||||
type PublicAccountAPI struct {
|
||||
|
@ -70,9 +70,17 @@ web3._extend({
|
||||
],
|
||||
properties:
|
||||
[
|
||||
new web3._extend.Property({
|
||||
name: 'content',
|
||||
getter: 'txpool_content'
|
||||
}),
|
||||
new web3._extend.Property({
|
||||
name: 'inspect',
|
||||
getter: 'txpool_inspect'
|
||||
}),
|
||||
new web3._extend.Property({
|
||||
name: 'status',
|
||||
getter: 'txpool_status'
|
||||
getter: 'txpool_status',
|
||||
outputFormatter: function(status) {
|
||||
status.pending = web3._extend.utils.toDecimal(status.pending);
|
||||
status.queued = web3._extend.utils.toDecimal(status.queued);
|
||||
|
Loading…
Reference in New Issue
Block a user