Skip to content
This repository has been archived by the owner on Jan 13, 2023. It is now read-only.

Commit

Permalink
Merge pull request #9 from itzmeanjan/develop
Browse files Browse the repository at this point in the history
Performance Improvement
  • Loading branch information
itzmeanjan authored Mar 31, 2021
2 parents 30c84ac + 1fc6e68 commit 95496cb
Show file tree
Hide file tree
Showing 11 changed files with 348 additions and 175 deletions.
12 changes: 8 additions & 4 deletions app/bootup/bootup.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,16 @@ func SetGround(ctx context.Context, file string) (*data.Resource, error) {

pool := &data.MemPool{
Pending: &data.PendingPool{
Transactions: make(map[common.Hash]*data.MemPoolTx),
Lock: &sync.RWMutex{},
Transactions: make(map[common.Hash]*data.MemPoolTx),
AscTxsByGasPrice: make(data.MemPoolTxsAsc, 0, 1024),
DescTxsByGasPrice: make(data.MemPoolTxsDesc, 0, 1024),
Lock: &sync.RWMutex{},
},
Queued: &data.QueuedPool{
Transactions: make(map[common.Hash]*data.MemPoolTx),
Lock: &sync.RWMutex{},
Transactions: make(map[common.Hash]*data.MemPoolTx),
AscTxsByGasPrice: make(data.MemPoolTxsAsc, 0, 1024),
DescTxsByGasPrice: make(data.MemPoolTxsDesc, 0, 1024),
Lock: &sync.RWMutex{},
},
}

Expand Down
79 changes: 79 additions & 0 deletions app/data/asc_gasprice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package data

// MemPoolTxsAsc - List of mempool tx(s)
//
// @note This structure to be used for sorting tx(s)
// in ascending way, using gas price they're paying
type MemPoolTxsAsc []*MemPoolTx

// len - Number of tx(s) present in this slice
func (m MemPoolTxsAsc) len() int {
return len(m)
}

// cap - Number of elements can be kept in slice
// without further memory allocation
func (m MemPoolTxsAsc) cap() int {
return cap(m)
}

// get - Return slice of txs
func (m MemPoolTxsAsc) get() []*MemPoolTx {
return m
}

// findInsertionPoint - Find index at which newly arrived tx should be entered to
// keep this slice sorted
func (m MemPoolTxsAsc) findInsertionPoint(low int, high int, tx *MemPoolTx) int {

if low > high {
return 0
}

if low == high {

if BigHexToBigDecimal(m[low].GasPrice).Cmp(BigHexToBigDecimal(tx.GasPrice)) > 0 {
return low
}

return low + 1

}

mid := (low + high) / 2
if BigHexToBigDecimal(m[mid].GasPrice).Cmp(BigHexToBigDecimal(tx.GasPrice)) > 0 {

return m.findInsertionPoint(low, mid, tx)

}

return m.findInsertionPoint(mid+1, high, tx)

}

// findTx - Find index of tx, which is already present in this sorted slice
func (m MemPoolTxsAsc) findTx(low int, high int, tx *MemPoolTx) int {

if low > high {
return -1
}

if low == high {

idx := findTxFromSlice(m[low:], tx)
if idx == -1 {
return -1
}

return low + idx

}

mid := (low + high) / 2
if BigHexToBigDecimal(m[mid].GasPrice).Cmp(BigHexToBigDecimal(tx.GasPrice)) >= 0 {
return m.findTx(low, mid, tx)
}

return m.findTx(mid+1, high, tx)

}
79 changes: 79 additions & 0 deletions app/data/desc_gasprice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package data

// MemPoolTxsDesc - List of mempool tx(s)
//
// @note This structure to be used for sorting tx(s)
// in descending way, using gas price they're paying
type MemPoolTxsDesc []*MemPoolTx

// len - Number of txs present in slice
func (m MemPoolTxsDesc) len() int {
return len(m)
}

// cap - Number of elements can be kept in slice
// without further memory allocation
func (m MemPoolTxsDesc) cap() int {
return cap(m)
}

// get - Return slice of txs
func (m MemPoolTxsDesc) get() []*MemPoolTx {
return m
}

// findInsertionPoint - Find index at which newly arrived tx should be entered to
// keep this slice sorted
func (m MemPoolTxsDesc) findInsertionPoint(low int, high int, tx *MemPoolTx) int {

if low > high {
return 0
}

if low == high {

if !(BigHexToBigDecimal(m[low].GasPrice).Cmp(BigHexToBigDecimal(tx.GasPrice)) > 0) {
return low
}

return low + 1

}

mid := (low + high) / 2
if !(BigHexToBigDecimal(m[mid].GasPrice).Cmp(BigHexToBigDecimal(tx.GasPrice)) > 0) {

return m.findInsertionPoint(low, mid, tx)

}

return m.findInsertionPoint(mid+1, high, tx)

}

// findTx - Find index of tx, which is already present in this sorted slice
func (m MemPoolTxsDesc) findTx(low int, high int, tx *MemPoolTx) int {

if low > high {
return -1
}

if low == high {

idx := findTxFromSlice(m[low:], tx)
if idx == -1 {
return -1
}

return low + idx

}

mid := (low + high) / 2
if !(BigHexToBigDecimal(m[mid].GasPrice).Cmp(BigHexToBigDecimal(tx.GasPrice)) > 0) {
return m.findTx(low, mid, tx)
}

return m.findTx(mid+1, high, tx)

}
87 changes: 26 additions & 61 deletions app/data/pending.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package data
import (
"context"
"log"
"sort"
"sync"
"time"

Expand All @@ -17,9 +16,10 @@ import (
// PendingPool - Currently present pending tx(s) i.e. which are ready to
// be mined in next block
type PendingPool struct {
Transactions map[common.Hash]*MemPoolTx
SortedTxs MemPoolTxsDesc
Lock *sync.RWMutex
Transactions map[common.Hash]*MemPoolTx
AscTxsByGasPrice TxList
DescTxsByGasPrice TxList
Lock *sync.RWMutex
}

// Get - Given tx hash, attempts to find out tx in pending pool, if any
Expand Down Expand Up @@ -55,7 +55,7 @@ func (p *PendingPool) Count() uint64 {
p.Lock.RLock()
defer p.Lock.RUnlock()

return uint64(len(p.Transactions))
return uint64(p.AscTxsByGasPrice.len())

}

Expand All @@ -82,7 +82,7 @@ func (p *PendingPool) DuplicateTxs(hash common.Hash) []*MemPoolTx {

result := make([]*MemPoolTx, 0, p.Count())

for _, tx := range p.Transactions {
for _, tx := range p.DescTxsByGasPrice.get() {

// First checking if tx under radar is the one for which
// we're finding duplicate tx(s). If yes, we will move to next one
Expand All @@ -94,9 +94,7 @@ func (p *PendingPool) DuplicateTxs(hash common.Hash) []*MemPoolTx {
// If yes, we'll include it considerable duplicate tx list, for given
// txHash
if tx.IsDuplicateOf(targetTx) {

result = append(result, tx)

}

}
Expand All @@ -111,13 +109,7 @@ func (p *PendingPool) ListTxs() []*MemPoolTx {
p.Lock.RLock()
defer p.Lock.RUnlock()

result := make([]*MemPoolTx, 0, len(p.Transactions))

for _, v := range p.Transactions {
result = append(result, v)
}

return result
return p.DescTxsByGasPrice.get()

}

Expand All @@ -128,11 +120,7 @@ func (p *PendingPool) TopXWithHighGasPrice(x uint64) []*MemPoolTx {
p.Lock.RLock()
defer p.Lock.RUnlock()

if txs := p.SortedTxs; txs != nil {
return txs[:x]
}

return nil
return p.DescTxsByGasPrice.get()[:x]

}

Expand All @@ -143,11 +131,7 @@ func (p *PendingPool) TopXWithLowGasPrice(x uint64) []*MemPoolTx {
p.Lock.RLock()
defer p.Lock.RUnlock()

if txs := p.SortedTxs; txs != nil {
return txs[len(txs)-int(x):]
}

return nil
return p.AscTxsByGasPrice.get()[:x]

}

Expand All @@ -158,9 +142,9 @@ func (p *PendingPool) SentFrom(address common.Address) []*MemPoolTx {
p.Lock.RLock()
defer p.Lock.RUnlock()

result := make([]*MemPoolTx, 0, len(p.SortedTxs))
result := make([]*MemPoolTx, 0, p.Count())

for _, tx := range p.SortedTxs {
for _, tx := range p.DescTxsByGasPrice.get() {

if tx.IsSentFrom(address) {
result = append(result, tx)
Expand All @@ -179,9 +163,9 @@ func (p *PendingPool) SentTo(address common.Address) []*MemPoolTx {
p.Lock.RLock()
defer p.Lock.RUnlock()

result := make([]*MemPoolTx, 0, len(p.SortedTxs))
result := make([]*MemPoolTx, 0, p.Count())

for _, tx := range p.SortedTxs {
for _, tx := range p.DescTxsByGasPrice.get() {

if tx.IsSentTo(address) {
result = append(result, tx)
Expand All @@ -200,9 +184,9 @@ func (p *PendingPool) OlderThanX(x time.Duration) []*MemPoolTx {
p.Lock.RLock()
defer p.Lock.RUnlock()

result := make([]*MemPoolTx, 0, len(p.Transactions))
result := make([]*MemPoolTx, 0, p.Count())

for _, tx := range p.Transactions {
for _, tx := range p.DescTxsByGasPrice.get() {

if tx.IsPendingForGTE(x) {
result = append(result, tx)
Expand All @@ -221,9 +205,9 @@ func (p *PendingPool) FresherThanX(x time.Duration) []*MemPoolTx {
p.Lock.RLock()
defer p.Lock.RUnlock()

result := make([]*MemPoolTx, 0, len(p.Transactions))
result := make([]*MemPoolTx, 0, p.Count())

for _, tx := range p.Transactions {
for _, tx := range p.DescTxsByGasPrice.get() {

if tx.IsPendingForLTE(x) {
result = append(result, tx)
Expand Down Expand Up @@ -259,6 +243,11 @@ func (p *PendingPool) Add(ctx context.Context, pubsub *redis.Client, tx *MemPool
// After adding new tx in pending pool, also attempt to
// publish it to pubsub topic
p.PublishAdded(ctx, pubsub, tx)

// Insert into sorted pending tx list, keep sorted
p.AscTxsByGasPrice = Insert(p.AscTxsByGasPrice, tx)
p.DescTxsByGasPrice = Insert(p.DescTxsByGasPrice, tx)

return true

}
Expand All @@ -276,9 +265,7 @@ func (p *PendingPool) PublishAdded(ctx context.Context, pubsub *redis.Client, ms
}

if err := pubsub.Publish(ctx, config.GetPendingTxEntryPublishTopic(), _msg).Err(); err != nil {

log.Printf("[❗️] Failed to publish new pending tx : %s\n", err.Error())

}

}
Expand Down Expand Up @@ -310,6 +297,10 @@ func (p *PendingPool) Remove(ctx context.Context, pubsub *redis.Client, txStat *
// Publishing this confirmed tx
p.PublishRemoved(ctx, pubsub, tx)

// Remove from sorted tx list, keep it sorted
p.AscTxsByGasPrice = Remove(p.AscTxsByGasPrice, tx)
p.DescTxsByGasPrice = Remove(p.DescTxsByGasPrice, tx)

delete(p.Transactions, txStat.Hash)

return true
Expand All @@ -331,9 +322,7 @@ func (p *PendingPool) PublishRemoved(ctx context.Context, pubsub *redis.Client,
}

if err := pubsub.Publish(ctx, config.GetPendingTxExitPublishTopic(), _msg).Err(); err != nil {

log.Printf("[❗️] Failed to publish confirmed tx : %s\n", err.Error())

}

}
Expand Down Expand Up @@ -483,27 +472,3 @@ func (p *PendingPool) AddPendings(ctx context.Context, pubsub *redis.Client, txs
return count

}

// SortTxs - Sorts current pending tx list ascendingly
// as per gas price paid by senders
//
// @note This is supposed to be invoked after every time you add
// new tx(s) to pending pool
func (p *PendingPool) SortTxs() bool {

txs := MemPoolTxsDesc(p.ListTxs())

if len(txs) == 0 {
return false
}

sort.Sort(&txs)

p.Lock.Lock()
defer p.Lock.Unlock()

p.SortedTxs = txs

return true

}
Loading

0 comments on commit 95496cb

Please sign in to comment.