Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transaction filter #5

Merged
merged 21 commits into from
Apr 8, 2024
107 changes: 107 additions & 0 deletions serve/filters/filter/tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package filter

import (
"github.com/gnolang/gno/tm2/pkg/bft/types"
)

type Options struct {
notJoon marked this conversation as resolved.
Show resolved Hide resolved
GasUsed struct{ Min, Max *int64 }
GasWanted struct{ Min, Max *int64 }
GasLimit struct{ Min, Max *int64 }
}

// TxFilter holds a slice of transaction results.
// It provides methods to manipulate and query the transactions.
type TxFilter struct {
opts Options
*baseFilter
txs []*types.TxResult
}

// NewTxFilter creates a new TxFilter object.
func NewTxFilter(opts Options) *TxFilter {
return &TxFilter{
baseFilter: newBaseFilter(TxFilterType),
txs: make([]*types.TxResult, 0),
opts: opts,
}
}

// GetHashes iterates over all transactions in the filter and returns their hashes.
func (tf *TxFilter) GetHashes() [][]byte {
notJoon marked this conversation as resolved.
Show resolved Hide resolved
tf.Lock()
defer tf.Unlock()

hashes := make([][]byte, 0, len(tf.txs))

for _, txr := range tf.txs {
var hash []byte

if txr != nil && txr.Tx != nil {
hash = txr.Tx.Hash()
}

hashes = append(hashes, hash)
}

return hashes
}

func (tf *TxFilter) UpdateWithTx(tx *types.TxResult) {
tf.Lock()
defer tf.Unlock()

tf.txs = append(tf.txs, tx)
}

notJoon marked this conversation as resolved.
Show resolved Hide resolved
// Apply applies all added conditions to the transactions in the filter.
//
// It returns a slice of `TxResult` that satisfy all the conditions. If no conditions are set,
// it returns all transactions in the filter. Also, if the filter value is invalid filter will not
// be applied.
func (tf *TxFilter) Apply() []*types.TxResult {
tf.Lock()
defer tf.Unlock()

return checkOpts(tf.txs, tf.opts)
}

func checkOpts(txs []*types.TxResult, opts Options) []*types.TxResult {
filtered := make([]*types.TxResult, 0, len(txs))

for _, tx := range txs {
if checkFilterCondition(tx, opts) {
filtered = append(filtered, tx)
}
}

return filtered
}

func checkFilterCondition(tx *types.TxResult, opts Options) bool {
if opts.GasLimit.Max != nil && tx.Response.GasUsed > *opts.GasLimit.Max {
return false
}

if opts.GasLimit.Min != nil && tx.Response.GasUsed < *opts.GasLimit.Min {
return false
}

if opts.GasUsed.Max != nil && tx.Response.GasUsed > *opts.GasUsed.Max {
return false
}

if opts.GasUsed.Min != nil && tx.Response.GasUsed < *opts.GasUsed.Min {
return false
}

if opts.GasWanted.Max != nil && tx.Response.GasWanted > *opts.GasWanted.Max {
return false
}

if opts.GasWanted.Min != nil && tx.Response.GasWanted < *opts.GasWanted.Min {
return false
}

return true
}
Loading
Loading