core, eth, internal, miner: optimize txpool for quick ops

This commit is contained in:
Péter Szilágyi
2016-07-01 18:59:55 +03:00
parent 795b70423e
commit 0ef327bbee
14 changed files with 790 additions and 428 deletions

View File

@ -118,21 +118,25 @@ func (b *EthApiBackend) RemoveTx(txHash common.Hash) {
b.eth.txMu.Lock()
defer b.eth.txMu.Unlock()
b.eth.txPool.RemoveTx(txHash)
b.eth.txPool.Remove(txHash)
}
func (b *EthApiBackend) GetPoolTransactions() types.Transactions {
b.eth.txMu.Lock()
defer b.eth.txMu.Unlock()
return b.eth.txPool.GetTransactions()
var txs types.Transactions
for _, batch := range b.eth.txPool.Pending() {
txs = append(txs, batch...)
}
return txs
}
func (b *EthApiBackend) GetPoolTransaction(txHash common.Hash) *types.Transaction {
func (b *EthApiBackend) GetPoolTransaction(hash common.Hash) *types.Transaction {
b.eth.txMu.Lock()
defer b.eth.txMu.Unlock()
return b.eth.txPool.GetTransaction(txHash)
return b.eth.txPool.Get(hash)
}
func (b *EthApiBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
@ -149,7 +153,7 @@ func (b *EthApiBackend) Stats() (pending int, queued int) {
return b.eth.txPool.Stats()
}
func (b *EthApiBackend) TxPoolContent() (map[common.Address]core.TxList, map[common.Address]core.TxList) {
func (b *EthApiBackend) TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) {
b.eth.txMu.Lock()
defer b.eth.txMu.Unlock()

View File

@ -677,7 +677,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}
p.MarkTransaction(tx.Hash())
}
pm.txpool.AddTransactions(txs)
pm.txpool.AddBatch(txs)
default:
return errResp(ErrInvalidMsgCode, "%v", msg.Code)

View File

@ -23,6 +23,7 @@ import (
"crypto/ecdsa"
"crypto/rand"
"math/big"
"sort"
"sync"
"testing"
@ -89,9 +90,9 @@ type testTxPool struct {
lock sync.RWMutex // Protects the transaction pool
}
// AddTransactions appends a batch of transactions to the pool, and notifies any
// AddBatch appends a batch of transactions to the pool, and notifies any
// listeners if the addition channel is non nil
func (p *testTxPool) AddTransactions(txs []*types.Transaction) {
func (p *testTxPool) AddBatch(txs []*types.Transaction) {
p.lock.Lock()
defer p.lock.Unlock()
@ -101,15 +102,20 @@ func (p *testTxPool) AddTransactions(txs []*types.Transaction) {
}
}
// GetTransactions returns all the transactions known to the pool
func (p *testTxPool) GetTransactions() types.Transactions {
// Pending returns all the transactions known to the pool
func (p *testTxPool) Pending() map[common.Address]types.Transactions {
p.lock.RLock()
defer p.lock.RUnlock()
txs := make([]*types.Transaction, len(p.pool))
copy(txs, p.pool)
return txs
batches := make(map[common.Address]types.Transactions)
for _, tx := range p.pool {
from, _ := tx.From()
batches[from] = append(batches[from], tx)
}
for _, batch := range batches {
sort.Sort(types.TxByNonce(batch))
}
return batches
}
// newTestTransaction create a new dummy transaction.

View File

@ -97,12 +97,12 @@ var errorToString = map[int]string{
}
type txPool interface {
// AddTransactions should add the given transactions to the pool.
AddTransactions([]*types.Transaction)
// AddBatch should add the given transactions to the pool.
AddBatch([]*types.Transaction)
// GetTransactions should return pending transactions.
// Pending should return pending transactions.
// The slice should be modifiable by the caller.
GetTransactions() types.Transactions
Pending() map[common.Address]types.Transactions
}
// statusData is the network packet for the status message.

View File

@ -130,7 +130,7 @@ func testSendTransactions(t *testing.T, protocol int) {
for nonce := range alltxs {
alltxs[nonce] = newTestTransaction(testAccount, uint64(nonce), txsize)
}
pm.txpool.AddTransactions(alltxs)
pm.txpool.AddBatch(alltxs)
// Connect several peers. They should all receive the pending transactions.
var wg sync.WaitGroup

View File

@ -45,7 +45,10 @@ type txsync struct {
// syncTransactions starts sending all currently pending transactions to the given peer.
func (pm *ProtocolManager) syncTransactions(p *peer) {
txs := pm.txpool.GetTransactions()
var txs types.Transactions
for _, batch := range pm.txpool.Pending() {
txs = append(txs, batch...)
}
if len(txs) == 0 {
return
}