From d8f6730daa162022566b64afe8ac7ad820629311 Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Tue, 20 Jul 2021 22:46:24 +0530 Subject: [PATCH 1/8] gas price comparison --- app/data/tx.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/app/data/tx.go b/app/data/tx.go index 1e57584..6ab0172 100644 --- a/app/data/tx.go +++ b/app/data/tx.go @@ -2,6 +2,7 @@ package data import ( "context" + "math/big" "time" "github.com/ethereum/go-ethereum/common" @@ -186,6 +187,30 @@ func (m *MemPoolTx) IsUnstuck(ctx context.Context, rpc *rpc.Client) (bool, error } +// HasGasPriceMoreThan - Returns true if gas price of this tx +// is more than `X` +func (m *MemPoolTx) HasGasPriceMoreThan(x float64) bool { + gp, err := BigHexToBigFloat(m.GasPrice) + if err != nil { + return false + } + + given := big.NewFloat(x) + return gp.Cmp(given) == 1 +} + +// HasGasPriceLessThan - Returns true if gas price of this tx +// is less than `X` +func (m *MemPoolTx) HasGasPriceLessThan(x float64) bool { + gp, err := BigHexToBigFloat(m.GasPrice) + if err != nil { + return false + } + + given := big.NewFloat(x) + return gp.Cmp(given) == -1 +} + // ToMessagePack - Serialize to message pack encoded byte array format func (m *MemPoolTx) ToMessagePack() ([]byte, error) { From 546e2308230e003b785ff48941058c7266e7fc34 Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Tue, 20 Jul 2021 22:54:43 +0530 Subject: [PATCH 2/8] pending pool txs with higher/ lower than `X` Gwei gas price --- app/data/pending.go | 52 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/app/data/pending.go b/app/data/pending.go index 38ee6af..e38134f 100644 --- a/app/data/pending.go +++ b/app/data/pending.go @@ -975,6 +975,58 @@ func (p *PendingPool) FresherThanX(x time.Duration) []*MemPoolTx { } +// HigherThanX - Returns a list of txs which are paid with +// gas price > `X` +func (p *PendingPool) HigherThanX(x float64) []*MemPoolTx { + txs := p.DescListTxs() + if txs == nil { + return nil + } + + txCount := uint64(len(txs)) + result := make([]*MemPoolTx, 0, txCount) + + for i := 0; i < len(txs); i++ { + // Stop ASAP, because iterating over + // descending sorted ( w.r.t. gas price ) + // tx list + if !txs[i].HasGasPriceMoreThan(x) { + break + } + + result = append(result, txs[i]) + } + + CleanSlice(txs) + return result +} + +// LowerThanX - Returns a list of txs which are paid with +// gas price < `X` +func (p *PendingPool) LowerThanX(x float64) []*MemPoolTx { + txs := p.AscListTxs() + if txs == nil { + return nil + } + + txCount := uint64(len(txs)) + result := make([]*MemPoolTx, 0, txCount) + + for i := 0; i < len(txs); i++ { + // Stop ASAP, because iterating over + // ascending sorted ( w.r.t. gas price ) + // tx list + if !txs[i].HasGasPriceLessThan(x) { + break + } + + result = append(result, txs[i]) + } + + CleanSlice(txs) + return result +} + // Add - Attempts to add new tx found in pending pool into // harmony mempool, so that further manipulation can be performed on it // From a616a4ad2102611fb20f91d1e6aca93c99155dc5 Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Wed, 21 Jul 2021 07:38:05 +0530 Subject: [PATCH 3/8] get queued tx list having gas price > or < given --- app/data/pending.go | 4 ++-- app/data/queued.go | 52 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/app/data/pending.go b/app/data/pending.go index e38134f..b2e0fb7 100644 --- a/app/data/pending.go +++ b/app/data/pending.go @@ -975,7 +975,7 @@ func (p *PendingPool) FresherThanX(x time.Duration) []*MemPoolTx { } -// HigherThanX - Returns a list of txs which are paid with +// HigherThanX - Returns a list of pending txs which are paid with // gas price > `X` func (p *PendingPool) HigherThanX(x float64) []*MemPoolTx { txs := p.DescListTxs() @@ -1001,7 +1001,7 @@ func (p *PendingPool) HigherThanX(x float64) []*MemPoolTx { return result } -// LowerThanX - Returns a list of txs which are paid with +// LowerThanX - Returns a list of pending txs which are paid with // gas price < `X` func (p *PendingPool) LowerThanX(x float64) []*MemPoolTx { txs := p.AscListTxs() diff --git a/app/data/queued.go b/app/data/queued.go index ebcda9e..007b051 100644 --- a/app/data/queued.go +++ b/app/data/queued.go @@ -758,6 +758,58 @@ func (q *QueuedPool) FresherThanX(x time.Duration) []*MemPoolTx { } +// HigherThanX - Returns a list of queued txs which are paid with +// gas price > `X` +func (q *QueuedPool) HigherThanX(x float64) []*MemPoolTx { + txs := q.DescListTxs() + if txs == nil { + return nil + } + + txCount := uint64(len(txs)) + result := make([]*MemPoolTx, 0, txCount) + + for i := 0; i < len(txs); i++ { + // Stop ASAP, because iterating over + // descending sorted ( w.r.t. gas price ) + // tx list + if !txs[i].HasGasPriceMoreThan(x) { + break + } + + result = append(result, txs[i]) + } + + CleanSlice(txs) + return result +} + +// LowerThanX - Returns a list of queued txs which are paid with +// gas price < `X` +func (q *QueuedPool) LowerThanX(x float64) []*MemPoolTx { + txs := q.AscListTxs() + if txs == nil { + return nil + } + + txCount := uint64(len(txs)) + result := make([]*MemPoolTx, 0, txCount) + + for i := 0; i < len(txs); i++ { + // Stop ASAP, because iterating over + // ascending sorted ( w.r.t. gas price ) + // tx list + if !txs[i].HasGasPriceLessThan(x) { + break + } + + result = append(result, txs[i]) + } + + CleanSlice(txs) + return result +} + // Add - Attempts to add new tx found in pending pool into // harmony mempool, so that further manipulation can be performed on it // From 636d353b8edb05d90562ad44ebdd461bdb1fd0aa Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Wed, 21 Jul 2021 07:42:15 +0530 Subject: [PATCH 4/8] include txs with gas price >= or <= ( prev > or < ) --- app/data/pending.go | 4 ++-- app/data/pool.go | 2 ++ app/data/queued.go | 4 ++-- app/data/tx.go | 8 ++++---- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/data/pending.go b/app/data/pending.go index b2e0fb7..dfae066 100644 --- a/app/data/pending.go +++ b/app/data/pending.go @@ -976,7 +976,7 @@ func (p *PendingPool) FresherThanX(x time.Duration) []*MemPoolTx { } // HigherThanX - Returns a list of pending txs which are paid with -// gas price > `X` +// gas price >= `X` func (p *PendingPool) HigherThanX(x float64) []*MemPoolTx { txs := p.DescListTxs() if txs == nil { @@ -1002,7 +1002,7 @@ func (p *PendingPool) HigherThanX(x float64) []*MemPoolTx { } // LowerThanX - Returns a list of pending txs which are paid with -// gas price < `X` +// gas price <= `X` func (p *PendingPool) LowerThanX(x float64) []*MemPoolTx { txs := p.AscListTxs() if txs == nil { diff --git a/app/data/pool.go b/app/data/pool.go index 5a2607f..d4649e9 100644 --- a/app/data/pool.go +++ b/app/data/pool.go @@ -102,6 +102,8 @@ func (m *MemPool) QueuedForLTE(x time.Duration) []*MemPoolTx { return m.Queued.FresherThanX(x) } +func (m *MemPool) PendingWithGTE() {} + // PendingFrom - List of tx(s) pending from address // // @note These are going to be same nonce tx(s), only one of them will diff --git a/app/data/queued.go b/app/data/queued.go index 007b051..bfea797 100644 --- a/app/data/queued.go +++ b/app/data/queued.go @@ -759,7 +759,7 @@ func (q *QueuedPool) FresherThanX(x time.Duration) []*MemPoolTx { } // HigherThanX - Returns a list of queued txs which are paid with -// gas price > `X` +// gas price >= `X` func (q *QueuedPool) HigherThanX(x float64) []*MemPoolTx { txs := q.DescListTxs() if txs == nil { @@ -785,7 +785,7 @@ func (q *QueuedPool) HigherThanX(x float64) []*MemPoolTx { } // LowerThanX - Returns a list of queued txs which are paid with -// gas price < `X` +// gas price <= `X` func (q *QueuedPool) LowerThanX(x float64) []*MemPoolTx { txs := q.AscListTxs() if txs == nil { diff --git a/app/data/tx.go b/app/data/tx.go index 6ab0172..cee8fc2 100644 --- a/app/data/tx.go +++ b/app/data/tx.go @@ -188,7 +188,7 @@ func (m *MemPoolTx) IsUnstuck(ctx context.Context, rpc *rpc.Client) (bool, error } // HasGasPriceMoreThan - Returns true if gas price of this tx -// is more than `X` +// is more than or equals to `X` func (m *MemPoolTx) HasGasPriceMoreThan(x float64) bool { gp, err := BigHexToBigFloat(m.GasPrice) if err != nil { @@ -196,11 +196,11 @@ func (m *MemPoolTx) HasGasPriceMoreThan(x float64) bool { } given := big.NewFloat(x) - return gp.Cmp(given) == 1 + return gp.Cmp(given) >= 0 } // HasGasPriceLessThan - Returns true if gas price of this tx -// is less than `X` +// is less than or equals to `X` func (m *MemPoolTx) HasGasPriceLessThan(x float64) bool { gp, err := BigHexToBigFloat(m.GasPrice) if err != nil { @@ -208,7 +208,7 @@ func (m *MemPoolTx) HasGasPriceLessThan(x float64) bool { } given := big.NewFloat(x) - return gp.Cmp(given) == -1 + return gp.Cmp(given) <= 0 } // ToMessagePack - Serialize to message pack encoded byte array format From 2083d393e4ce9e7db1f0d05257ecdcdc4d77cec1 Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Wed, 21 Jul 2021 07:46:59 +0530 Subject: [PATCH 5/8] wrapper functions --- app/data/pool.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/app/data/pool.go b/app/data/pool.go index d4649e9..fe2c3a7 100644 --- a/app/data/pool.go +++ b/app/data/pool.go @@ -102,7 +102,25 @@ func (m *MemPool) QueuedForLTE(x time.Duration) []*MemPoolTx { return m.Queued.FresherThanX(x) } -func (m *MemPool) PendingWithGTE() {} +// PendingWithGTE - Returns list of tx(s), pending with gas price >= `X` +func (m *MemPool) PendingWithGTE(x float64) []*MemPoolTx { + return m.Pending.HigherThanX(x) +} + +// PendingWithLTE - Returns list of tx(s), pending with gas price <= `X` +func (m *MemPool) PendingWithLTE(x float64) []*MemPoolTx { + return m.Pending.LowerThanX(x) +} + +// QueuedWithGTE - Returns list of tx(s), queued with gas price >= `X` +func (m *MemPool) QueuedWithGTE(x float64) []*MemPoolTx { + return m.Queued.HigherThanX(x) +} + +// QueuedWithLTE - Returns list of tx(s), queued with gas price <= `X` +func (m *MemPool) QueuedWithLTE(x float64) []*MemPoolTx { + return m.Queued.LowerThanX(x) +} // PendingFrom - List of tx(s) pending from address // From 175f8def0332141fc309f45128e0df89db533273 Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Wed, 21 Jul 2021 07:52:07 +0530 Subject: [PATCH 6/8] grapphql handlers implemented --- app/graph/generated/generated.go | 346 +++++++++++++++++++++++++++++++ app/graph/schema.graphqls | 6 + app/graph/schema.resolvers.go | 32 +++ 3 files changed, 384 insertions(+) diff --git a/app/graph/generated/generated.go b/app/graph/generated/generated.go index 4a4f959..b65abf2 100644 --- a/app/graph/generated/generated.go +++ b/app/graph/generated/generated.go @@ -68,11 +68,15 @@ type ComplexityRoot struct { PendingForMoreThan func(childComplexity int, x string) int PendingFrom func(childComplexity int, addr string) int PendingTo func(childComplexity int, addr string) int + PendingWithLessThan func(childComplexity int, x float64) int + PendingWithMoreThan func(childComplexity int, x float64) int QueuedDuplicates func(childComplexity int, hash string) int QueuedForLessThan func(childComplexity int, x string) int QueuedForMoreThan func(childComplexity int, x string) int QueuedFrom func(childComplexity int, addr string) int QueuedTo func(childComplexity int, addr string) int + QueuedWithLessThan func(childComplexity int, x float64) int + QueuedWithMoreThan func(childComplexity int, x float64) int TopXPendingWithHighGasPrice func(childComplexity int, x int) int TopXPendingWithLowGasPrice func(childComplexity int, x int) int TopXQueuedWithHighGasPrice func(childComplexity int, x int) int @@ -120,6 +124,10 @@ type QueryResolver interface { TopXQueuedWithLowGasPrice(ctx context.Context, x int) ([]*model.MemPoolTx, error) PendingDuplicates(ctx context.Context, hash string) ([]*model.MemPoolTx, error) QueuedDuplicates(ctx context.Context, hash string) ([]*model.MemPoolTx, error) + PendingWithMoreThan(ctx context.Context, x float64) ([]*model.MemPoolTx, error) + PendingWithLessThan(ctx context.Context, x float64) ([]*model.MemPoolTx, error) + QueuedWithMoreThan(ctx context.Context, x float64) ([]*model.MemPoolTx, error) + QueuedWithLessThan(ctx context.Context, x float64) ([]*model.MemPoolTx, error) } type SubscriptionResolver interface { NewPendingTx(ctx context.Context) (<-chan *model.MemPoolTx, error) @@ -326,6 +334,30 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.PendingTo(childComplexity, args["addr"].(string)), true + case "Query.pendingWithLessThan": + if e.complexity.Query.PendingWithLessThan == nil { + break + } + + args, err := ec.field_Query_pendingWithLessThan_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.PendingWithLessThan(childComplexity, args["x"].(float64)), true + + case "Query.pendingWithMoreThan": + if e.complexity.Query.PendingWithMoreThan == nil { + break + } + + args, err := ec.field_Query_pendingWithMoreThan_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.PendingWithMoreThan(childComplexity, args["x"].(float64)), true + case "Query.queuedDuplicates": if e.complexity.Query.QueuedDuplicates == nil { break @@ -386,6 +418,30 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.QueuedTo(childComplexity, args["addr"].(string)), true + case "Query.queuedWithLessThan": + if e.complexity.Query.QueuedWithLessThan == nil { + break + } + + args, err := ec.field_Query_queuedWithLessThan_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.QueuedWithLessThan(childComplexity, args["x"].(float64)), true + + case "Query.queuedWithMoreThan": + if e.complexity.Query.QueuedWithMoreThan == nil { + break + } + + args, err := ec.field_Query_queuedWithMoreThan_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.QueuedWithMoreThan(childComplexity, args["x"].(float64)), true + case "Query.topXPendingWithHighGasPrice": if e.complexity.Query.TopXPendingWithHighGasPrice == nil { break @@ -769,6 +825,12 @@ type Query { pendingDuplicates(hash: String!): [MemPoolTx!]! queuedDuplicates(hash: String!): [MemPoolTx!]! + + pendingWithMoreThan(x: Float!): [MemPoolTx!]! + pendingWithLessThan(x: Float!): [MemPoolTx!]! + + queuedWithMoreThan(x: Float!): [MemPoolTx!]! + queuedWithLessThan(x: Float!): [MemPoolTx!]! } type Subscription { @@ -903,6 +965,36 @@ func (ec *executionContext) field_Query_pendingTo_args(ctx context.Context, rawA return args, nil } +func (ec *executionContext) field_Query_pendingWithLessThan_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 float64 + if tmp, ok := rawArgs["x"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("x")) + arg0, err = ec.unmarshalNFloat2float64(ctx, tmp) + if err != nil { + return nil, err + } + } + args["x"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_pendingWithMoreThan_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 float64 + if tmp, ok := rawArgs["x"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("x")) + arg0, err = ec.unmarshalNFloat2float64(ctx, tmp) + if err != nil { + return nil, err + } + } + args["x"] = arg0 + return args, nil +} + func (ec *executionContext) field_Query_queuedDuplicates_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -978,6 +1070,36 @@ func (ec *executionContext) field_Query_queuedTo_args(ctx context.Context, rawAr return args, nil } +func (ec *executionContext) field_Query_queuedWithLessThan_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 float64 + if tmp, ok := rawArgs["x"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("x")) + arg0, err = ec.unmarshalNFloat2float64(ctx, tmp) + if err != nil { + return nil, err + } + } + args["x"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_queuedWithMoreThan_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 float64 + if tmp, ok := rawArgs["x"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("x")) + arg0, err = ec.unmarshalNFloat2float64(ctx, tmp) + if err != nil { + return nil, err + } + } + args["x"] = arg0 + return args, nil +} + func (ec *executionContext) field_Query_topXPendingWithHighGasPrice_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -2414,6 +2536,174 @@ func (ec *executionContext) _Query_queuedDuplicates(ctx context.Context, field g return ec.marshalNMemPoolTx2ᚕᚖgithubᚗcomᚋitzmeanjanᚋharmonyᚋappᚋgraphᚋmodelᚐMemPoolTxᚄ(ctx, field.Selections, res) } +func (ec *executionContext) _Query_pendingWithMoreThan(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_pendingWithMoreThan_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().PendingWithMoreThan(rctx, args["x"].(float64)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.MemPoolTx) + fc.Result = res + return ec.marshalNMemPoolTx2ᚕᚖgithubᚗcomᚋitzmeanjanᚋharmonyᚋappᚋgraphᚋmodelᚐMemPoolTxᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_pendingWithLessThan(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_pendingWithLessThan_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().PendingWithLessThan(rctx, args["x"].(float64)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.MemPoolTx) + fc.Result = res + return ec.marshalNMemPoolTx2ᚕᚖgithubᚗcomᚋitzmeanjanᚋharmonyᚋappᚋgraphᚋmodelᚐMemPoolTxᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_queuedWithMoreThan(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_queuedWithMoreThan_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().QueuedWithMoreThan(rctx, args["x"].(float64)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.MemPoolTx) + fc.Result = res + return ec.marshalNMemPoolTx2ᚕᚖgithubᚗcomᚋitzmeanjanᚋharmonyᚋappᚋgraphᚋmodelᚐMemPoolTxᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query_queuedWithLessThan(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_queuedWithLessThan_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().QueuedWithLessThan(rctx, args["x"].(float64)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]*model.MemPoolTx) + fc.Result = res + return ec.marshalNMemPoolTx2ᚕᚖgithubᚗcomᚋitzmeanjanᚋharmonyᚋappᚋgraphᚋmodelᚐMemPoolTxᚄ(ctx, field.Selections, res) +} + func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -4983,6 +5273,62 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr } return res }) + case "pendingWithMoreThan": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_pendingWithMoreThan(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) + case "pendingWithLessThan": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_pendingWithLessThan(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) + case "queuedWithMoreThan": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_queuedWithMoreThan(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) + case "queuedWithLessThan": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_queuedWithLessThan(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "__type": out.Values[i] = ec._Query___type(ctx, field) case "__schema": diff --git a/app/graph/schema.graphqls b/app/graph/schema.graphqls index 6311ce4..36bf440 100644 --- a/app/graph/schema.graphqls +++ b/app/graph/schema.graphqls @@ -37,6 +37,12 @@ type Query { pendingDuplicates(hash: String!): [MemPoolTx!]! queuedDuplicates(hash: String!): [MemPoolTx!]! + + pendingWithMoreThan(x: Float!): [MemPoolTx!]! + pendingWithLessThan(x: Float!): [MemPoolTx!]! + + queuedWithMoreThan(x: Float!): [MemPoolTx!]! + queuedWithLessThan(x: Float!): [MemPoolTx!]! } type Subscription { diff --git a/app/graph/schema.resolvers.go b/app/graph/schema.resolvers.go index 1577c76..4b3e8e0 100644 --- a/app/graph/schema.resolvers.go +++ b/app/graph/schema.resolvers.go @@ -128,6 +128,38 @@ func (r *queryResolver) QueuedDuplicates(ctx context.Context, hash string) ([]*m return toGraphQL(memPool.QueuedDuplicates(common.HexToHash(hash))), nil } +func (r *queryResolver) PendingWithMoreThan(ctx context.Context, x float64) ([]*model.MemPoolTx, error) { + if !(x >= 0) { + return nil, errors.New("bad gas price ( in Gwei )") + } + + return toGraphQL(memPool.PendingWithGTE(x)), nil +} + +func (r *queryResolver) PendingWithLessThan(ctx context.Context, x float64) ([]*model.MemPoolTx, error) { + if !(x >= 0) { + return nil, errors.New("bad gas price ( in Gwei )") + } + + return toGraphQL(memPool.PendingWithLTE(x)), nil +} + +func (r *queryResolver) QueuedWithMoreThan(ctx context.Context, x float64) ([]*model.MemPoolTx, error) { + if !(x >= 0) { + return nil, errors.New("bad gas price ( in Gwei )") + } + + return toGraphQL(memPool.QueuedWithGTE(x)), nil +} + +func (r *queryResolver) QueuedWithLessThan(ctx context.Context, x float64) ([]*model.MemPoolTx, error) { + if !(x >= 0) { + return nil, errors.New("bad gas price ( in Gwei )") + } + + return toGraphQL(memPool.QueuedWithLTE(x)), nil +} + func (r *subscriptionResolver) NewPendingTx(ctx context.Context) (<-chan *model.MemPoolTx, error) { _pubsub, err := SubscribeToPendingTxEntry(ctx) if err != nil { From f8a06c277fe495af6df96b04e6f4c81a9969d3f1 Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Wed, 21 Jul 2021 08:02:57 +0530 Subject: [PATCH 7/8] added doc --- README.md | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/README.md b/README.md index 88f045d..31ed8bc 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ Reduce Chaos in MemPool 😌 - [Inspecting tx(s) in pending pool](#pending-pool) - [Pending For >= `X`](#pending-for-more-than-X) - [Pending For <= `X`](#pending-for-less-than-X) + - [Pending With >= `X` ( Gwei )](#pending-with-more-than-X) + - [Pending With <= `X` ( Gwei )](#pending-with-less-than-X) - [Pending From Address `A`](#pending-from-A) - [Pending To Address `A`](#pending-to-A) - [Top `X` Pending Tx(s)](#top-X-pending) @@ -37,6 +39,8 @@ Reduce Chaos in MemPool 😌 - [Inspecting tx(s) in queued pool](#queued-pool) - [Queued For >= `X`](#queued-for-more-than-X) - [Queued For <= `X`](#queued-for-less-than-X) + - [Queued With >= `X` ( Gwei )](#queued-with-more-than-X) + - [Queued With <= `X` ( Gwei )](#queued-with-less-than-X) - [Queued From Address `A`](#queued-from-A) - [Queued To Address `A`](#queued-to-A) - [Top `X` Queued Tx(s)](#top-X-queued) @@ -427,6 +431,48 @@ query { --- +### Pending with more than `X` + +For listing all tx(s) pending with gas price >= `x` GWei, send graphQL query + +Method : **POST** + +URL : **/v1/graphql** + + +```graphql +query { + pendingWithMoreThan(x: 20.1) { + from + hash + gasPriceGwei + } +} +``` + +--- + +### Pending with less than `X` + +For listing all tx(s) pending with gas price <= `x` GWei, send graphQL query + +Method : **POST** + +URL : **/v1/graphql** + + +```graphql +query { + pendingWithLessThan(x: 10.1) { + from + hash + gasPriceGwei + } +} +``` + +--- + ### Pending from `A` For getting a list of all pending tx(s) `from` specific address, send a graphQL query like 👇 @@ -839,6 +885,48 @@ query { --- +### Queued with more than `X` + +For listing all tx(s) queued with gas price >= `x` GWei, send graphQL query + +Method : **POST** + +URL : **/v1/graphql** + + +```graphql +query { + queuedWithMoreThan(x: 20.1) { + from + hash + gasPriceGwei + } +} +``` + +--- + +### Queued with less than `X` + +For listing all tx(s) queued with gas price <= `x` GWei, send graphQL query + +Method : **POST** + +URL : **/v1/graphql** + + +```graphql +query { + queuedWithLessThan(x: 10.1) { + from + hash + gasPriceGwei + } +} +``` + +--- + ### Queued from `A` For getting a list of all queued tx(s) `from` specific address, send a graphQL query like 👇 From ef745a652724134f2d22b38efa7478968d451ed2 Mon Sep 17 00:00:00 2001 From: Anjan Roy Date: Wed, 21 Jul 2021 20:37:44 +0530 Subject: [PATCH 8/8] convert to gwei --- app/data/tx.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/data/tx.go b/app/data/tx.go index cee8fc2..44f70d7 100644 --- a/app/data/tx.go +++ b/app/data/tx.go @@ -195,7 +195,7 @@ func (m *MemPoolTx) HasGasPriceMoreThan(x float64) bool { return false } - given := big.NewFloat(x) + given := big.NewFloat(x * 1_000_000_000) return gp.Cmp(given) >= 0 } @@ -207,7 +207,7 @@ func (m *MemPoolTx) HasGasPriceLessThan(x float64) bool { return false } - given := big.NewFloat(x) + given := big.NewFloat(x * 1_000_000_000) return gp.Cmp(given) <= 0 }