Reduce Chaos in MemPool 😌

Overview

harmony

Reduce Chaos in MemPool 😌

banner

Table of Contents

Motivation

I discovered Ethereum's MemPool is one of the least explored domains, but not really least important.

Whenever a block is mined & some tx(s) are included in it, it's pretty much, value living at rest, whereas is case of mempool, value is in-flight. A lot of tx(s) are fighting for their space in next block to be mined, where only a few will get their place. But who will get, based or what criteria, it's not very much well defined.

We generally believe giving higher gas price compared to other tx(s) currently present in mempool, gives better chance that block miner will pick this tx during next block mining. But block miner always gets to override that, using custom logic. Also any one can write an automated program for monitoring mempool and replicate tx(s) of their interest with their own address, higher gas price - which may help them in cutting deal faster than original one or benefitting if target smart contract has some security loophole.

During my journey of exploring Ethereum MemPool, I found good initiative from BlockNative in demystifying MemPool. They've built some interesting products on top of mempool.

harmony - Reduce Chaos in MemPool 😌, aims to become a reliable mempool monitoring engine, while exposing useful functionalities for letting client applications write their monitoring logic seamlessly, with out worrying about underlying details too much 😎

  • You can subscribe to listen for tx(s) going to/ from address of interest
  • You can catch duplicate nonce tx(s), which of them gets accepted/ dropped
  • You can build notification service on top of it
  • It will help you in getting better gas price prediction
  • It can be used for building real-time charts showing current network traffic
  • Many more ...

Prerequisite

  • Make sure you've Go ( >= 1.16), make installed
  • You need to also have Redis ( >= 5.x )

Note : Consider setting up Redis instance with password protection

  • Get one Ethereum Node up & running, with txpool RPC API enabled. You can always use SaaS Ethereum node.

Installation

  • For using harmony, let's first clone this repo
git clone https://github.com/itzmeanjan/harmony.git
  • After getting inside harmony, create .env file with πŸ‘‡ content
cd harmony
touch .env
RPCUrl=https://<rpc-node>
MemPoolPollingPeriod=1000
PendingTxEntryTopic=pending_pool_entry
PendingTxExitTopic=pending_pool_exit
QueuedTxEntryTopic=queued_pool_entry
QueuedTxExitTopic=queued_pool_exit
RedisConnection=tcp
RedisAddress=127.0.0.1:6379
RedisPassword=password
RedisDB=1
ConcurrencyFactor=10
Port=7000
Environment Variable Interpretation
RPCUrl txpool RPC API enabled Ethereum Node's URI
MemPoolPollingPeriod RPC node's mempool to be checked every X milliseconds
PendingTxEntryTopic Whenever tx enters pending pool, it'll be published on Redis topic t
PendingTxExitTopic Whenever tx leaves pending pool, it'll be published on Redis topic t
QueuedTxEntryTopic Whenever tx enters queued pool, it'll be published on Redis topic t
QueuedTxExitTopic Whenever tx leaves queued pool, it'll be published on Redis topic t
RedisConnection Communicate with Redis over transport protocol
RedisAddress address:port combination of Redis
RedisPassword Authentication details for talking to Redis. [ Not mandatory ]
RedisDB Redis database to be used. [ By default there're 16 of them ]
ConcurrencyFactor Whenever concurrency can be leveraged, harmony will create worker pool with #-of logical CPUs x ConcurrencyFactor go routines. [ Can be float too ]
Port Starts HTTP server on this port ( > 1024 )
  • Let's build & run harmony
make run

Usage

Status of MemPool

For checking current state of mempool, you can issue one HTTP GET request

Method : GET

URL : /v1/stat

curl -s localhost:7000/v1/stat | jq

You'll receive response like πŸ‘‡

{
  "pendingPoolSize": 67,
  "queuedPoolSize": 0,
  "uptime": "29.214603s",
  "networkID": 137
}
Field Interpretation
pendingPoolSize Currently these many tx(s) are in pending state i.e. waiting to be picked up by some miner when next block gets mined
queuedPoolSize These tx(s) are stuck, will only be eligible for mining when lower nonce tx(s) of same wallet gets mined
uptime This mempool monitoring engine is alive for last t time unit
networkID The mempool monitoring engine keeps track of mempool of this network

Catching Any Mempool Changes

Whenever any change in mempool pool happens i.e. tx joins/ leaves pending/ queued pool, subscriber will be notified of those.

  • Tx joins queued pool, when it's stuck due to some nonce gap
  • It'll leave queued pool, when it's unstuck & lower nonce tx is processed
  • Tx joins pending pool, when it's ready to be included in next block [ though might not ]
  • Tx leaves pool, when tx it has been included in just mined block

Aforementioned changes generally happen in mempool & using following subscription API lets you capture all of those.

Transport : WebSocket

URL : /v1/graphql

subscription {
  memPool{
    from
    to
    gasPrice
	pool
	pendingFor
	queuedFor
  }
}

Catching Tx(s) From A in Mempool

When some new tx joins either of queued/ pending pool & that tx is sent from address A, subscriber to be notified of it.

When that tx will leave pool, client to be notified.

Transport : WebSocket

URL : /v1/graphql

subscription {
  newTxFromAInMemPool{
    from
    to
    gasPrice
	pool
	pendingFor
	queuedFor
  }
}

Catching Tx(s) To A in Mempool

When some new tx joins either of queued/ pending pool & that tx is sent to address A, subscriber to be notified of it.

When that tx will leave pool, client to be notified.

Contract creation tx(s) will have empty to field

Transport : WebSocket

URL : /v1/graphql

subscription {
  newTxToAInMemPool{
    from
    to
    gasPrice
	pool
	pendingFor
	queuedFor
  }
}

Pending Pool

Pending pool inspection related APIs.

Pending for more than X

For listing all tx(s) pending for more than or equals to x time unit, send graphQL query

Method : POST

URL : /v1/graphql

query {
  pendingForMoreThan(x: "10s") {
    from
  	gas
  	gasPrice
  	hash
  	input
  	nonce
  	to
  	value
  	v
  	r
  	s
  	pendingFor
  	queuedFor
  	pool
  }
}

You'll receive response of form

{
  "data": {
    "pendingForMoreThan": [
      {
        "from": "0xdF0692E287A763e5c011cc96Ee402994c6Dd246E",
        "gas": "35743",
        "gasPrice": "74 Gwei",
        "hash": "0x142f95b4615ad31d5435fb979a07405d50b70a2dab2707001cdb04853b75537e",
        "input": "0x22c67519000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000001e35",
        "nonce": "108",
        "to": "0x86935F11C86623deC8a25696E1C19a8659CbF95d",
        "value": "0x0",
        "v": "0x136",
        "r": "0x4becd37941425526e5a1d361a44fd5f911affacaa5526e42e7a20c4a9fb04f90",
        "s": "0x3052c55bf6ac67326b4adb92c9ff3288ffe0f0be829b726c2a1cf5b9a58dca5c",
        "pendingFor": "10.677797s",
        "queuedFor": "0 s",
        "pool": "pending"
      }
    ]
  }
}

Pending for less than X

For listing all tx(s) pending for less than or equals to x time unit, send graphQL query

Method : POST

URL : /v1/graphql

query {
  pendingForLessThan(x: "1m10s") {
    from
  	gas
  	gasPrice
  	hash
  	input
  	nonce
  	to
  	value
  	v
  	r
  	s
  	pendingFor
  	queuedFor
  	pool
  }
}

Pending from A

For getting a list of all pending tx(s) from specific address, send a graphQL query like πŸ‘‡

Note : More than one pending tx from same address, denotes those are same nonce tx(s).

Method : POST

URL : /v1/graphql

query {
  pendingFrom(addr: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313") {
    from
  	gas
  	gasPrice
  	hash
  	input
  	nonce
  	to
  	value
  	v
  	r
  	s
  	pendingFor
  	queuedFor
  	pool
  }
}

Pending to A

For getting a list of all pending tx(s) sent to specific address, you can send a graphQL query like πŸ‘‡

Method : POST

URL : /v1/graphql

query {
  pendingTo(addr: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313") {
    from
  	gas
  	gasPrice
  	hash
  	input
  	nonce
  	to
  	value
  	v
  	r
  	s
  	pendingFor
  	queuedFor
  	pool
  }
}

Top X pending

Top X pending transaction(s), with high gas price

Method : POST

URL : /v1/graphql

query {
  topXPendingWithHighGasPrice(x: 10) {
    from
  	gas
  	gasPrice
  	hash
  	input
  	nonce
  	to
  	value
  	v
  	r
  	s
  	pendingFor
  	queuedFor
  	pool
  }
}

Top X pending transaction(s), with low gas price

Method : POST

URL : /v1/graphql

query {
  topXPendingWithLowGasPrice(x: 10) {
    from
  	gas
  	gasPrice
  	hash
  	input
  	nonce
  	to
  	value
  	v
  	r
  	s
  	pendingFor
  	queuedFor
  	pool
  }
}

Pending Duplicate Tx(s)

Given txHash, attempts to find out duplicate tx(s) present in pending pool.

Tx is considered to be duplicate, when it has, same sender address & nonce

Method : POST

URL : /v1/graphql

query {
  pendingDuplicates(hash: "0x2d17f2941e33afd3a648e3257857ed032191b7b93911364ba4906d640ca69b49") {
    from
	to
  	gas
  	gasPrice
  	hash
  	nonce
  	pendingFor
  	queuedFor
  	pool
  }
}

New pending tx(s)

Listening for any new tx, being added to pending pool, in real-time, over websocket transport

gql_subscription

Transport : WebSocket

URL : /v1/graphql

subscription {
  newPendingTx{
    from
    to
    gas
    gasPrice
    nonce
  }
}

New confirmed tx(s)

Listening for any new tx, leaving pending pool i.e. confirmed, in real-time, over websocket transport

Transport : WebSocket

URL : /v1/graphql

subscription {
  newConfirmedTx{
    from
    to
    gasPrice
  }
}

Pending Pool Changes

Whenever any change in pending tx pool happens i.e. tx joins/ leaves pool, subscriber will be notified of those

  • Tx joins pending pool, when it's ready to be included in next block [ though might not ]
  • Tx leaves pool, when tx it has been included in just mined block

Transport : WebSocket

URL : /v1/graphql

subscription {
  pendingPool{
    from
    to
    gasPrice
	pool
  }
}

New pending tx(s) from

When ever any tx is detected to be entering pending pool, where from address is matching with specified one, subscriber will be notified of it.

Transport : WebSocket

URL : /v1/graphql

subscription {
  newPendingTxFrom(address: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313"){
    from
    to
    gasPrice
  }
}

New confirmed tx(s) from

When ever any tx is detected to be leaving pending pool i.e. got included in some block, where from address is matching with specified one, subscriber will be notified of it.

Transport : WebSocket

URL : /v1/graphql

subscription {
  newConfirmedTxFrom(address: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313"){
    from
    to
    gasPrice
  }
}

Catching new pending tx from A

When new tx, sent from address A, is detected to be entering pending pool, client to be notified. Also when tx will be confirmed, they will be notified, that tx has left pending pool.

Transport : WebSocket

URL : /v1/graphql

subscription {
  newTxFromAInPendingPool(address: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313"){
    from
    to
    gasPrice
	pendingFor
	queuedFor
  }
}

New pending tx(s) to

When ever any tx is detected to be entering pending pool, where to address is matching with specified one, subscriber will be notified of it.

Note: Tx(s) attempting to deploy contract, will have no to address

Transport : WebSocket

URL : /v1/graphql

subscription {
  newPendingTxTo(address: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313"){
    from
    to
    gasPrice
  }
}

New confirmed tx(s) to

When ever any tx is detected to be leaving pending pool i.e. got included in some block, where to address is matching with specified one, subscriber will be notified of it.

Transport : WebSocket

URL : /v1/graphql

subscription {
  newConfirmedTxTo(address: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313"){
    from
    to
    gasPrice
  }
}

Catching new pending tx to A

When new tx, where recipient address is A, is detected to be entering pending pool, client to be notified. Also when tx will be confirmed, they will be notified, that tx has left pending pool.

Transport : WebSocket

URL : /v1/graphql

subscription {
  newTxToAInPendingPool(address: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313"){
    from
    to
    gasPrice
	pendingFor
	queuedFor
  }
}

Queued Pool

Queued tx pool inspection APIs.

Queued for more than X

For listing all tx(s) queued for more than or equals to x time unit, send graphQL query

Method : POST

URL : /v1/graphql

query {
  queuedForMoreThan(x: "1h10m39s") {
    from
  	gas
  	gasPrice
  	hash
  	input
  	nonce
  	to
  	value
  	v
  	r
  	s
  	pendingFor
  	queuedFor
  	pool
  }
}

Queued for less than X

For listing all tx(s) queued for less than or equals to x time unit, send graphQL query

Method : POST

URL : /v1/graphql

query {
  queuedForLessThan(x: "1m10s100ms") {
    from
  	gas
  	gasPrice
  	hash
  	input
  	nonce
  	to
  	value
  	v
  	r
  	s
  	pendingFor
  	queuedFor
  	pool
  }
}

Queued from A

For getting a list of all queued tx(s) from specific address, send a graphQL query like πŸ‘‡

Note : These are present in queued pool due to nonce gap in sender's address i.e. there must be some tx with lower nonce present in pending pool & until that one gets mined, these tx(s) in queued pool, will not move into pending pool.

Method : POST

URL : /v1/graphql

query {
  queuedFrom(addr: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313") {
    from
  	gas
  	gasPrice
  	hash
  	input
  	nonce
  	to
  	value
  	v
  	r
  	s
  	pendingFor
  	queuedFor
  	pool
  }
}

Queued to A

For getting a list of all queued tx(s) sent to specific address, you can send a graphQL query like πŸ‘‡

Method : POST

URL : /v1/graphql

query {
  queuedTo(addr: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313") {
    from
  	gas
  	gasPrice
  	hash
  	input
  	nonce
  	to
  	value
  	v
  	r
  	s
  	pendingFor
  	queuedFor
  	pool
  }
}

Top X pending

Top X queued transaction(s), with high gas price

Method : POST

URL : /v1/graphql

query {
  topXQueuedWithHighGasPrice(x: 10) {
    from
  	gas
  	gasPrice
  	hash
  	input
  	nonce
  	to
  	value
  	v
  	r
  	s
  	pendingFor
  	queuedFor
  	pool
  }
}

Top X queued transaction(s), with low gas price

Method : POST

URL : /v1/graphql

query {
  topXQueuedWithLowGasPrice(x: 10) {
    from
  	gas
  	gasPrice
  	hash
  	input
  	nonce
  	to
  	value
  	v
  	r
  	s
  	pendingFor
  	queuedFor
  	pool
  }
}

Queued Duplicate Tx(s)

Given txHash, attempts to find out duplicate tx(s) present in queued pool.

Tx is considered to be duplicate, when it has, same sender address & nonce

Method : POST

URL : /v1/graphql

query {
  queuedDuplicates(hash: "0x2d17f2941e33afd3a648e3257857ed032191b7b93911364ba4906d640ca69b49") {
    from
	to
  	gas
  	gasPrice
  	hash
  	nonce
  	pendingFor
  	queuedFor
  	pool
  }
}

New queued tx(s)

Listening for any new tx, being added to queued pool, in real-time, over websocket transport

Transport : WebSocket

URL : /v1/graphql

subscription {
  newQueuedTx{
    from
    to
    gas
    gasPrice
    nonce
  }
}

New unstuck tx(s)

Listening for any new tx, leaving queued tx pool i.e. unstuck, in real-time, over websocket transport

Transport : WebSocket

URL : /v1/graphql

subscription {
  newUnstuckTx{
    from
    to
    gasPrice
  }
}

Queued Pool Changes

Whenever any change in queued tx pool happens i.e. tx joins/ leaves pool, subscriber will be notified of those

  • Tx joins queued pool, due to some issue in sender's account [ mostly nonce gap ], because it's not eligible for inclusion in next block to be mined
  • Tx leaves pool, when lower nonce has been filled up & this stuck tx is now ready to get included in block [ It's unstuck now ]

Transport : WebSocket

URL : /v1/graphql

subscription {
  queuedPool{
    from
    to
    gasPrice
	pool
  }
}

New queued tx(s) from

When ever any tx is detected to be entering queued pool ( because they're stuck due to nonce gap ), where from address is matching with specified one, subscriber will be notified of it.

Transport : WebSocket

URL : /v1/graphql

subscription {
  newQueuedTxFrom(address: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313"){
    from
    to
    gasPrice
  }
}

New unstuck tx(s) from

When ever any tx is detected to be leaving queued pool ( because they were stuck due to nonce gap ), where from address is matching with specified one, subscriber will be notified of it.

Transport : WebSocket

URL : /v1/graphql

subscription {
  newUnstuckTxFrom(address: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313"){
    from
    to
    gasPrice
  }
}

Catching new queued tx from A

When new tx, from address A, is detected to be entering queued pool, client to be notified. Also when that tx will be unstuck, client will be notified, that tx has left queued pool & it's now eligible to enter pending pool & become candidate tx for next block to be mined.

Transport : WebSocket

URL : /v1/graphql

subscription {
  newTxFromAInQueuedPool(address: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313"){
    from
    to
    gasPrice
	pendingFor
	queuedFor
  }
}

New queued tx(s) to

When ever any tx is detected to be entering queued pool ( because they're stuck due to nonce gap ), where to address is matching with specified one, subscriber will be notified of it.

Transport : WebSocket

URL : /v1/graphql

subscription {
  newQueuedTxTo(address: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313"){
    from
    to
    gasPrice
  }
}

New unstuck tx(s) to

When ever any tx is detected to be leaving queued pool ( because they were stuck due to nonce gap ), where to address is matching with specified one, subscriber will be notified of it.

Transport : WebSocket

URL : /v1/graphql

subscription {
  newUnstuckTxTo(address: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313"){
    from
    to
    gasPrice
  }
}

Catching new queued tx to A

When new tx, targeted to address A, is detected to be entering queued pool, client to be notified. Also when tx will be unstuck, they will be notified, that tx has left queued pool & it's now eligible to enter pending pool & become candidate tx for next block to be mined.

Transport : WebSocket

URL : /v1/graphql

subscription {
  newTxToAInQueuedPool(address: "0x63ec5767F54F6943750A70eB6117EA2D9Ca77313"){
    from
    to
    gasPrice
	pendingFor
	queuedFor
  }
}

GraphQL Playground

harmony packs one graphQL playground for you, where you can play around with both query & subscription methods.

query works over HTTP transport, where as subscription works only over Websocket transport.

graphql_playground

URI : https://<base-url>/v1/graphql-playground

GraphQL Query/ Subscription Examples

I've written some examples for programmatically querying GraphQL API over HTTP & subscribing to topics for listening to MemPool state changes in real-time, over Websocket transport.

gql_subscription_example

You can find those here. Before you run those

  • Make sure you've Python3 installed. They're tested to be working on Python 3.9.2
  • Let's first enable virtual environment, by doing
cd examples
python3 -m venv venv
source venv/bin/activate
  • We can now fetch dependencies, by doing
pip install -r requirements.txt
  • You can now run any of examples, by doing
python3 query.py
python3 subscribe_1.py

Make sure, you've access to harmony node.

  • Finally when you're done, you can get out of virtual environment
deactivate

Note: harmony is not recommended for use in production environment at time of writing this. It's under active development.


Comments
  • Querying Mempool with GraphQL

    Querying Mempool with GraphQL

    Changes

    • Exposing graphql methods for querying latest state of mempool
    • Get tx(s) present in mempool i.e. {pending, queued} for >=, <= T, time unit
    • Also one graphql playground ✌️

    image

    opened by itzmeanjan 2
  • ❗ Failed to fetch block and Only transactions will be added, but completed transactions will not be removed;

    ❗ Failed to fetch block and Only transactions will be added, but completed transactions will not be removed;

    Hi, brother. During my testing, I found two problems:

    1. Only transactions will be added, but completed transactions will not be removed;
    2. Failed to fetch block:14294800 (error is: transaction type not supported)
    // ProcessBlock - Fetches all txs present in mined block & passes those to pending pool pruning worker
    func ProcessBlock(ctx context.Context, client *ethclient.Client, number *big.Int, commChan chan<- CaughtTxs, lastSeenBlockChan chan<- uint64) bool {
    	block, err := client.BlockByNumber(ctx, number)
    	if err != nil {
    		log.Printf("❗️ Failed to fetch block : %d\n %s \n", number, err) ---->(erris: transaction type not supported)
    		return false
    	}
    

    I need you help,thank you very much!


      / __/___/ /  ___
     / _// __/ _ \/ _ \
    /___/\__/_//_/\___/ v4.2.0
    High performance, minimalist Go web framework
    https://echo.labstack.com
    ____________________________________O/_______
                                        O\
    ⇨ http server started on [::]:7000
    2022/02/28 13:38:41 [βž•] Added 10119 tx(s) to queued tx pool, in 1.689134982s
    2022/02/28 13:38:41 [βž•] Added 457 tx(s) to pending tx pool, in 51.14923ms
    2022/02/28 13:38:41 ❇️ Pending Tx(s) : 457 | Queued Tx(s) : 10119, in 2.846309757s
    2022/02/28 13:38:42 [βž•] Added 7 tx(s) to queued tx pool, in 69.33677ms
    2022/02/28 13:38:42 [βž•] Added 34 tx(s) to pending tx pool, in 7.169083ms
    2022/02/28 13:38:42 ❇️ Pending Tx(s) : 491 | Queued Tx(s) : 10126, in 1.106247426s
    2022/02/28 13:38:43 [βž•] Added 10 tx(s) to pending tx pool, in 4.576167ms
    2022/02/28 13:38:43 ❇️ Pending Tx(s) : 501 | Queued Tx(s) : 10125, in 1.164577285s
    2022/02/28 13:38:44 [βž•] Added 18 tx(s) to pending tx pool, in 5.957062ms
    2022/02/28 13:38:44 ❇️ Pending Tx(s) : 519 | Queued Tx(s) : 10125, in 1.172117117s
    2022/02/28 13:38:45 [βž•] Added 11 tx(s) to pending tx pool, in 5.706903ms
    2022/02/28 13:38:45 ❇️ Pending Tx(s) : 530 | Queued Tx(s) : 10125, in 1.094710133s
    2022/02/28 13:38:46 [βž•] Added 3 tx(s) to queued tx pool, in 59.130545ms
    2022/02/28 13:38:46 [βž•] Added 18 tx(s) to pending tx pool, in 5.359677ms
    2022/02/28 13:38:46 ❇️ Pending Tx(s) : 548 | Queued Tx(s) : 10128, in 1.059802306s
    2022/02/28 13:38:49 [βž•] Added 16 tx(s) to pending tx pool, in 5.592977ms
    2022/02/28 13:38:49 ❇️ Pending Tx(s) : 564 | Queued Tx(s) : 10128, in 2.59863857s
    2022/02/28 13:38:51 [βž•] Added 1 tx(s) to queued tx pool, in 63.535859ms
    2022/02/28 13:38:51 [βž•] Added 36 tx(s) to pending tx pool, in 5.930608ms
    2022/02/28 13:38:51 ❇️ Pending Tx(s) : 600 | Queued Tx(s) : 10129, in 2.248649639s
    2022/02/28 13:38:53 [βž•] Added 2 tx(s) to queued tx pool, in 71.964043ms
    2022/02/28 13:38:53 [βž•] Added 118 tx(s) to pending tx pool, in 23.964072ms
    2022/02/28 13:38:53 ❇️ Pending Tx(s) : 718 | Queued Tx(s) : 10131, in 1.368934871s
    2022/02/28 13:38:54 [βž•] Added 20 tx(s) to pending tx pool, in 8.262592ms
    2022/02/28 13:38:54 ❇️ Pending Tx(s) : 738 | Queued Tx(s) : 10130, in 1.249005267s
    2022/02/28 13:38:55 [βž•] Added 1 tx(s) to queued tx pool, in 65.833426ms
    2022/02/28 13:38:55 [βž•] Added 12 tx(s) to pending tx pool, in 7.169755ms
    2022/02/28 13:38:55 ❇️ Pending Tx(s) : 750 | Queued Tx(s) : 10131, in 1.283568372s
    2022/02/28 13:38:56 [βž•] Added 10 tx(s) to pending tx pool, in 6.476501ms
    2022/02/28 13:38:56 ❇️ Pending Tx(s) : 760 | Queued Tx(s) : 10131, in 1.123001223s
    2022/02/28 13:38:58 [βž•] Added 1 tx(s) to queued tx pool, in 64.265631ms
    2022/02/28 13:38:58 [βž•] Added 23 tx(s) to pending tx pool, in 9.541043ms
    2022/02/28 13:38:58 ❇️ Pending Tx(s) : 783 | Queued Tx(s) : 10132, in 1.300504424s
    2022/02/28 13:38:59 [βž•] Added 4 tx(s) to queued tx pool, in 57.305082ms
    2022/02/28 13:38:59 [βž•] Added 35 tx(s) to pending tx pool, in 7.423574ms
    2022/02/28 13:38:59 ❇️ Pending Tx(s) : 818 | Queued Tx(s) : 10135, in 1.211386451s
    2022/02/28 13:39:00 [βž•] Added 13 tx(s) to pending tx pool, in 5.248855ms
    2022/02/28 13:39:00 ❇️ Pending Tx(s) : 831 | Queued Tx(s) : 10134, in 1.078215911s
    2022/02/28 13:39:05 [βž•] Added 5 tx(s) to queued tx pool, in 102.491104ms
    2022/02/28 13:39:05 [βž•] Added 12 tx(s) to pending tx pool, in 5.874882ms
    2022/02/28 13:39:05 ❇️ Pending Tx(s) : 843 | Queued Tx(s) : 10139, in 5.221286546s
    2022/02/28 13:39:06 [βž•] Added 10 tx(s) to queued tx pool, in 72.461747ms
    2022/02/28 13:39:07 [βž•] Added 44 tx(s) to pending tx pool, in 8.327105ms
    2022/02/28 13:39:07 ❇️ Pending Tx(s) : 887 | Queued Tx(s) : 10148, in 1.33273809s
    2022/02/28 13:39:08 [βž•] Added 1 tx(s) to queued tx pool, in 67.475553ms
    2022/02/28 13:39:08 [βž•] Added 44 tx(s) to pending tx pool, in 9.34013ms
    2022/02/28 13:39:08 ❇️ Pending Tx(s) : 932 | Queued Tx(s) : 10147, in 1.097033077s
    2022/02/28 13:39:09 [βž•] Added 13 tx(s) to pending tx pool, in 3.924495ms
    2022/02/28 13:39:09 ❇️ Pending Tx(s) : 945 | Queued Tx(s) : 10145, in 1.223074494s
    2022/02/28 13:39:10 [βž•] Added 2 tx(s) to queued tx pool, in 63.137728ms
    2022/02/28 13:39:10 [βž•] Added 8 tx(s) to pending tx pool, in 4.184372ms
    2022/02/28 13:39:10 ❇️ Pending Tx(s) : 953 | Queued Tx(s) : 10147, in 1.4534464s
    2022/02/28 13:39:12 [βž–] Removed 10 tx(s) from queued tx pool
    2022/02/28 13:39:12 [βž•] Added 28 tx(s) to pending tx pool, in 8.849301ms
    2022/02/28 13:39:12 ❇️ Pending Tx(s) : 981 | Queued Tx(s) : 10146, in 1.227720543s
    2022/02/28 13:39:13 [βž•] Added 2 tx(s) to queued tx pool, in 68.985141ms
    2022/02/28 13:39:13 [βž•] Added 18 tx(s) to pending tx pool, in 5.884856ms
    2022/02/28 13:39:13 ❇️ Pending Tx(s) : 999 | Queued Tx(s) : 10146, in 1.111469165s
    2022/02/28 13:39:14 [βž•] Added 15 tx(s) to pending tx pool, in 5.15586ms
    2022/02/28 13:39:14 ❇️ Pending Tx(s) : 1014 | Queued Tx(s) : 10146, in 1.520474802s
    2022/02/28 13:39:16 [βž•] Added 21 tx(s) to pending tx pool, in 5.802966ms
    2022/02/28 13:39:16 ❇️ Pending Tx(s) : 1035 | Queued Tx(s) : 10146, in 1.932619267s
    2022/02/28 13:39:17 [βž•] Added 17 tx(s) to pending tx pool, in 5.911145ms
    
    --------------------------Out Log---------------------------------------------
    2022/02/28 13:02:10 ❇️ Pending Tx(s) : 1016 | Queued Tx(s) : 11854, in 1.395611208s
    2022/02/28 13:02:12 [βž•] Added 2 tx(s) to queued tx pool, in 69.049747ms
    2022/02/28 13:02:12 [βž•] Added 13 tx(s) to pending tx pool, in 8.059417ms
    2022/02/28 13:02:12 ❇️ Pending Tx(s) : 1029 | Queued Tx(s) : 11856, in 1.55538375s
    2022/02/28 13:02:13 πŸ” header.Number 14294800 block(s)
    2022/02/28 13:02:13 ❗ Failed to fetch block : 14294800
    ------------------------------Code-------------------------------------------
          log.Printf("πŸ” header.Number %d block(s)\n", header.Number)
          if !ProcessBlock(ctx, client, header.Number, commChan, lastSeenBlockChan) {
            // Put entry in table that we failed to fetch this block, to be
            // attempted in some time future
            retryTable[header.Number] = struct{}{}
          }
    -----------------------------Code---------------------------------------------
    // ProcessBlock - Fetches all txs present in mined block & passes those to pending pool pruning worker
    func ProcessBlock(ctx context.Context, client *ethclient.Client, number *big.Int, commChan chan<- CaughtTxs, lastSeenBlockChan chan<- uint64) bool {
    	block, err := client.BlockByNumber(ctx, number)
    	if err != nil {
    		log.Printf("❗ Failed to fetch block : %d\n", number)
    		return false
    	}
    -------------------------------------------------------------------------
    
    opened by DarkFunct 1
  • Failed to fetch mempool content : the method txpool_content does not exist/is not available

    Failed to fetch mempool content : the method txpool_content does not exist/is not available

    2022/02/13 07:27:21 [😌] Harmony - Reducing Chaos in MemPool 2022/02/13 07:27:21 [❃] Running in solo mode


    / // / ___ / // / _ / _
    /
    /_
    ////___/ v4.2.0 High performance, minimalist Go web framework https://echo.labstack.com _____________________________O/ O
    ⇨ http server started on [::]:7000 2022/02/13 07:27:21 [❗️] Failed to fetch mempool content : the method txpool_content does not exist/is not available 2022/02/13 07:27:21 ❗️ Block header subscription failed 2022/02/13 07:27:21 [βœ…] Gracefully shut down harmony after 8.188836ms

    can u help me?

    opened by DarkFunct 1
  • Integrated `pub0sub`

    Integrated `pub0sub`

    What's new ?

    After experimenting with pub0sub - Fast, Lightweight Pub/Sub over TCP, QUIC - powered by Async I/O; for some time I've decided to use it with harmony for Pub/Sub.

    As pub0sub's Pub/Sub server 0hub is built using async I/O, it'll hopefully perform well.

    Under testing !!!

    opened by itzmeanjan 1
  • Update {Pending, Queued}MemPool with latest `txpool_content`

    Update {Pending, Queued}MemPool with latest `txpool_content`

    Changes

    • Periodically keep polling txpool_content for latest state of mempool
    • Attempt to update internal data structures with latest data
    • Keep track of discovery_time for each tx(s) found in either queued/ pending pool
    • After each iteration of fetching latest mempool state, publish changes ( only changes ) to pubsub topic [ WIP ]

    image

    opened by itzmeanjan 1
  • GraphQL New Queries

    GraphQL New Queries

    What's new ?

    As I wanted to query mempool for existence of transactions with gas price >= or <= specified gas price, I've added respective GraphQL queries for both pending & queued pool.

    Now one can get list of all pending txs with gas price >= 20.1 ( Gwei ).

    query {
      pendingWithMoreThan(x: 20.1) {
    	from
    	hash
    	gasPriceGwei
      }
    }
    

    For <= 10 Gwei, make use of query pendingWithLessThan(x: 10) { ... }.

    README.md has documentation around it.

    Note: Gas price provided/ represented in Gwei

    opened by itzmeanjan 0
  • GraphQL New Field Addition

    GraphQL New Field Addition

    Why ?

    I'm interested in obtaining gasPrice GraphQL field as float, which is why I add gasPriceGwei field which returns gas price in Gwei unit as floating point number ( double precision ).

    Now GraphQL queries can also be written as

    query {
      pendingForMoreThan(x: "10s") {
        gasPriceGwei
        nonce
      }
    }
    
    opened by itzmeanjan 0
  • Replace Redis with `pubsub`

    Replace Redis with `pubsub`

    What's new ?

    Redis was used for in-app messaging leveraging Single Producer Multiple Consumers/ Multiple Producers Multiple Consumers patterns, built around topics. But I recently wrote one embeddable, light-weight pub/sub system pubsub & Redis Pub/Sub being replaced with pubsub which is sleek, lean & doesn't make network calls πŸ”₯

    This is being tested now.

    opened by itzmeanjan 0
  • Reduce overtime memory usage

    Reduce overtime memory usage

    Why ?

    Both pending & queued pool keeps track of which tx(s) were removed because they were dropped/ confirmed/ unstuck & this memory usage overtime becomes a problem.

    If we keep removing those entries from tracker table which were seen long time back ( > 1 hour ), we can free some memory. 1 hour is just a random number being used, in hope, after 1 hour of last time it was attempted to be added into pool it is probably not there for again added into pool. This may not be true, if RPC node being relied on, doesn't feed us with fresh data.

    opened by itzmeanjan 0
  • Supervising Block Header Listener Worker

    Supervising Block Header Listener Worker

    Why ?

    Block header listen go routine can crash due to several reasons, so it's better to handle that by catching when it crashes & spawning new worker which can continue where its previous worker left off.

    opened by itzmeanjan 0
  • Track slowly propagated tx(s)

    Track slowly propagated tx(s)

    Why ?

    Some times mempool tx propagation takes more time than usual & mempool tx is received when it's actually mined. I'm going to keep track of which mined txs I couldn't find in pending pool & later time when same tx joins mempool as pending one, I'll let pending pool pruning worker know, this tx is actually mined.

    Hopefully solving our problem.

    Being tested on mainnet now

    opened by itzmeanjan 0
  •  Failed to publish tx ... pool : connection already teared down

    Failed to publish tx ... pool : connection already teared down

    Got this error in the console while running the program. The subscription feature also does not work, it just endlessly loads. I assume these issues are connected. The pub0 has been configured with default settings and is running in the background. The log starts by saying listening on xyz. Then it constantly switches from connected to disconnected

    harmony console

    pub0 logs .

    opened by mgpai22 14
  • Failed to acquire resource(s) : tls: first record does not look like a TLS handshake

    Failed to acquire resource(s) : tls: first record does not look like a TLS handshake

    ------------------------- RUN ------------------------------ user@fly9:~/Source/harmony$ ./harmony 2021/08/22 17:54:57 [😌] Harmony - Reducing Chaos in MemPool 2021/08/22 17:54:57 [❗️] Failed to acquire resource(s) : tls: first record does not look like a TLS handshake

    ------------------------- ENV FILE ------------------------- user@fly9:~/Source/harmony$ cat .env RPCUrl=https://localhost:8545 WSUrl=wss://localhost:8546 MemPoolPollingPeriod=1000 PendingPoolSize=4096 QueuedPoolSize=4096 PendingTxEntryTopic=pending_pool_entry PendingTxExitTopic=pending_pool_exit QueuedTxEntryTopic=queued_pool_entry QueuedTxExitTopic=queued_pool_exit ConcurrencyFactor=10 Port=7000 Pub0SubHost=127.0.0.1 Pub0SubPort=13000

    --------------------------------- NETSTAT PORT CHECK OF GETH ------------------------- user@fly9:~/Source/harmony$ netstat -nalptl | grep geth | grep 85 | grep -v EST tcp 0 0 127.0.0.1:8545 0.0.0.0:* LISTEN 2264523/geth
    tcp 0 0 127.0.0.1:8546 0.0.0.0:* LISTEN 2264523/geth

    --------------------------------- GETH VERSION ------------------------------------------- user@fly9:~$ geth version Geth Version: 1.10.6-stable Git Commit: 576681f29b895dd39e559b7ba17fcd89b42e4833 Architecture: amd64 Go Version: go1.16.4 Operating System: linux

    --------------------------------- HARMONY VERSION ------------------------------------- commit 4572d3712321cdaeb20e3313067f71ad3b3268dd (HEAD -> main, tag: v0.9.5, origin/main, origin/HEAD)

    --------------------------------- WIRESHARK SCEENSHOT if it helps ---------------------- image

    opened by dimdumon 1
Releases(v0.9.5)
  • v0.9.5(Jul 23, 2021)

    What's new ?

    • I'm now using Pub/Sub Hub 0hub for publishing transactions joining/ leaving {pending, queued} pool
    • Added new graphql query methods for finding out all txs waiting in {pending, queued} pool with gas price >= or <= specified one
    • Now transaction gas price can be queried in numeric form, using graphql field gasPriceGwei
    Source code(tar.gz)
    Source code(zip)
  • v0.9.4(May 9, 2021)

    What's new ?

    Just a dependency version update, which introduced one race condition.

    Library pubsub was not handling access to shared variable with locks, was resolved here ✌️

    All set βœ…

    Source code(tar.gz)
    Source code(zip)
  • v0.9.3(May 8, 2021)

    What's new ? πŸ€”

    Previously for communicating new tx(s) ( joining/ leaving mempool ) to clients subscribing to various topics, Redis Pub/Sub was used. Recently I also worked on developing one in-app messaging library for Go projects called pubsub, which leverages native Go functionalities for enabling in-app message passing in following patterns

    • SPSC
    • SPMC
    • MPSC
    • MPMC

    You can read more about that library here

    I decided to use pubsub, replacing Redis Pub/Sub. It after through testing everything seemed to fit well.

    And here's release flaunting pubsub in harmony πŸ”₯

    ✌️

    Source code(tar.gz)
    Source code(zip)
  • v0.9.2(May 3, 2021)

    What's new ? πŸ€”

    • Cleans up occupied memory, used for keeping track of dropped/ confirmed/ unstuck tx(s)
    • Overtime this memory usage won't become a problem anymore
    • After 1 hour tracked txHashes are pruned as of now, which can be made more flexible 🧐
    Source code(tar.gz)
    Source code(zip)
  • v0.9.1(Apr 25, 2021)

    What's new ? πŸ€”

    Just added one go routine supervisor go routine, which will keep track of block header listener worker's health & if header listener dies in mid, new worker to be spawn up to take its place after a while. It'll also process those blocks which were produced during offtime.

    Source code(tar.gz)
    Source code(zip)
  • v0.9.0(Apr 19, 2021)

    What's new ? πŸ€”

    • Consider slowly propagated tx(s), using buffered queue of tx(s) which are included in mined block, but could not be found in mempool immediately
    • Prune them later when they're propagated through network & received by harmony

    Solving dangling tx(s) issue, which are actually mined, but used to be considered as pending

    Source code(tar.gz)
    Source code(zip)
  • v0.8.1(Apr 18, 2021)

    What's new ?

    /v1/stat API has been updated to include more info

    {
      "pendingPoolSize": 113569,
      "queuedPoolSize": 22768,
      "uptime": "14h59m12.066436482s",
      "processed": 822953,
      "latestBlock": 12261127,
      "latestSeenAgo": "7.876590164s",
      "networkID": 1
    }
    
    Source code(tar.gz)
    Source code(zip)
  • v0.8.0(Apr 14, 2021)

    What's new ?

    • After extensively running it with Ethereum Mainnet, under high tx pressure, it has shown good performance while processing inbound/ outbound tx(s) 😎
    • Also packs lots of improvement in how state is managed in each of pending/ queued pool
    • All operations are concurrent safe, with out using any locking primitives, all powered by go routines & channels
    • Using better data structures, give us better performance
    • You can also ask harmony to not consume whole memory, by setting {Pending, Queued}PoolSize fields
    Source code(tar.gz)
    Source code(zip)
  • v0.7.0(Apr 10, 2021)

    What's new ? πŸ₯³

    • Avoiding lock-contention as much as possible, using channels more
    • Lazily prune pending/ queued pool state
    • Subscribe to block header(s) for learning about which block is including which tx(s) & prune those if seen in mempool
    • All utility methods build on top of mempool, will be leveraging multiple cores ( if available )

    ✌️

    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Mar 31, 2021)

    What's new ?

    • Improved in-memory state management πŸ₯³
    • Response time lesser than before, as lots of queries are ready to answered βœ…
    • Overall better performance that before
    • Now P2P network's peer connections are protected with NOISE
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Mar 29, 2021)

    What's new ? 🧐

    • harmony cluster set up [ P2P networking ]
    • Better & much larger view of Ethereum Mempool, when using multi-node cluster set up [ Details in README ]
    • Length prefixed MessagePack serialised binary data stream passed between harmony peers over TCP, when ever change is detected
    • Reduced scope of lock contention when dealing with shared state from multiple go routines

    πŸ₯³

    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Mar 22, 2021)

    What's new ?

    • Improved performance, when clients query current state of mempool over GraphQL API, resulting in lower response delay 😎
    • Handling dropped tx(s), users can subscribe to watch tx of interest, to be notified anything linked with that tx happens in mempool πŸš€
      • They'll be notified of new speed up/ cancellation tx(s)
    • Examples added for using new watcher API πŸ˜‰

    πŸ₯³

    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Mar 13, 2021)

    What's new ? πŸ€”

    • New GraphQL subscription methods for listening to tx(s)
      • Joining/ Leaving mempool 😎
      • Joining/ Leaving {pending/ queued} pool ✌️ [ More granular version of 1st one ]
      • Afore mentioned versions with from/ to address based tx filtering πŸ₯³
    • New GraphQL query method for detecting duplicate nonce tx(s) in mempool, given txHash
    • Improved calculation of how long tx(s) spent in which section of mempool πŸ•‘

    Cheers πŸ₯³

    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Mar 10, 2021)

    What's new ? πŸ€”

    • Subscribe to MemPool changes, over WebSocket transport, for listening to any tx entering/ leaving pool
    • Also it's possible to selectively listen to tx(s) having certain from/ to address. As soon as they enter/ leave mempool, client will be notified.

    Cheers πŸ₯³

    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Mar 8, 2021)

    What's new ?

    • harmony - Reduce Chaos in MemPool, hopes to help developers in getting better look inside mempool. And for facilitating so, it exposes some GraphQL APIs, for inspecting current state of mempool.
    • You can inspect either pending/ queued pool, using those APIs
    • There's a GraphQL playground attached with harmony binary, which can be used for exploring APIs
    • Read more about it here

    Note : This is not a production grade release. harmony is still under active development & you're very welcome in helping us bettering it.

    Source code(tar.gz)
    Source code(zip)
Owner
Anjan Roy
Learning :)
Anjan Roy
EVM Liquidity Sniper Bot consuming GETH txs through the mempool

AX-50 Liquidity Sniper This bot requires you to run the GETH client + use ethers framework. Supports any EVM environment and UniSwapV2 forked AMM seem

Santi Aguilera 128 Jan 6, 2023
A simple program able to listen to the pending transactions of the Ethereum mempool. Written in Go.

eth-mempool-listener-go A simple program able to listen to the pending transactions of the Ethereum mempool. How does it work ? It creates a set of cl

Luca G.F. 24 Dec 26, 2022
:alarm_clock: :fire: A TCP proxy to simulate network and system conditions for chaos and resiliency testing

Toxiproxy Toxiproxy is a framework for simulating network conditions. It's made specifically to work in testing, CI and development environments, supp

Shopify 8.8k Jan 7, 2023
HTTP mocking to test API services for chaos scenarios

GAOS HTTP mocking to test API services for chaos scenarios Gaos, can create and provide custom mock restful services via using your fully-customizable

Trendyol Open Source 211 Nov 5, 2022
Litmus helps Kubernetes SREs and developers practice chaos engineering in a Kubernetes native way.

Litmus Cloud-Native Chaos Engineering Read this in other languages. ???? ???? ???? ???? Overview Litmus is a toolset to do cloud-native chaos engineer

Litmus Chaos 3.4k Jan 1, 2023
A function for chaos testing with OpenFaaS

chaos-fn A function for chaos testing with OpenFaaS Use-cases Test retries on certain HTTP codes Test timeouts Test certain lengths of HTTP request bo

Alex Ellis 4 May 26, 2022
Chaos Engineering tool for introducing failure into syscalls

Syscall monkey Chaos Engineering tool for tampering with syscalls.

null 7 Jun 11, 2022
Toxiproxy - A TCP proxy to simulate network and system conditions for chaos and resiliency testing

Toxiproxy is a framework for simulating network conditions. It's made specifically to work in testing, CI and development environments, supp

Shopify 6.7k Nov 3, 2021
The test suite to demonstrate the chaos experiment behavior in different scenarios

Litmus-E2E The goal of litmus e2e is to provide the test suite to demonstrate the chaos experiment behavior in different scenarios. As the name sugges

Vedant Shrotria 0 Jul 7, 2022
Chaosblade executor for chaos experiments on Java applications

Chaosblade-exec-jvm: Chaosblade executor for chaos experiments on Java applications Introduction The project is a chaosblade executor based on jvm-san

null 349 Dec 16, 2022
Chaostheory task1 - This is repository for Chaos Theory Internship Program

Chaos Theory Internship - Take Home Task. Hyeonwoo KIM(clo3olb) City Universiry

Hyeonwoo Kim 0 Feb 11, 2022
Fast, efficient, and scalable distributed map/reduce system, DAG execution, in memory or on disk, written in pure Go, runs standalone or distributedly.

Gleam Gleam is a high performance and efficient distributed execution system, and also simple, generic, flexible and easy to customize. Gleam is built

Chris Lu 3.1k Jan 1, 2023
Reduce debugging time while programming Go. Use static and stack-trace analysis to determine which func call causes the error.

Errlog: reduce debugging time while programming Introduction Use errlog to improve error logging and speed up debugging while you create amazing code

Martin Joly 412 Nov 18, 2022
Fast, efficient, and scalable distributed map/reduce system, DAG execution, in memory or on disk, written in pure Go, runs standalone or distributedly.

Gleam Gleam is a high performance and efficient distributed execution system, and also simple, generic, flexible and easy to customize. Gleam is built

Chris Lu 3.2k Jan 5, 2023
Map, Reduce, Filter, De/Multiplex, etc. for the Go language.

proto proto gives Go operations like Map, Reduce, Filter, De/Multiplex, etc. without sacrificing idiomatic harmony or speed. It also introduces a conv

Erich Blume 59 Nov 17, 2022
Go library for writing standalone Map/Reduce jobs or for use with Hadoop's streaming protocol

dmrgo is a Go library for writing map/reduce jobs. It can be used with Hadoop's streaming protocol, but also includes a standalone map/reduce impleme

Damian Gryski 103 Nov 27, 2022
Reduce maintainer fatigue by automating GitHub

derek Derek reduces fatigue for maintainers by automating governance and delegating permissions to your team and community. Follow @derekapp on Twitte

Alex Ellis 783 Dec 23, 2022
"there" also called "GoThere" aims to be a simple Go Library to reduce redundant code for REST APIs.

there "there" also called "GoThere" aims to be a simple Go Library to reduce redundant code for REST APIs. Despite the existence of the other librarie

Christoph Krassnigg 43 Dec 25, 2022