Skip to content

Commit

Permalink
proto: add txn_signature filter (#445)
Browse files Browse the repository at this point in the history
  • Loading branch information
fanatid authored Nov 2, 2024
1 parent 9093464 commit 5ac20df
Show file tree
Hide file tree
Showing 6 changed files with 456 additions and 404 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The minor version will be incremented upon a breaking change and the patch versi
- proto: add filter by lamports ([#369](https://github.com/rpcpool/yellowstone-grpc/pull/369))
- geyser: use Arc wrapped messages in block message ([#446](https://github.com/rpcpool/yellowstone-grpc/pull/446))
- node: remove generated grpc files ([#447](https://github.com/rpcpool/yellowstone-grpc/pull/447))
- proto: add txn_signature filter ([#445](https://github.com/rpcpool/yellowstone-grpc/pull/445))

### Breaking

Expand Down
820 changes: 417 additions & 403 deletions examples/golang/proto/geyser.pb.go

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions examples/rust/src/bin/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ struct ActionSubscribe {
#[clap(long)]
accounts: bool,

/// Filter by presence of field txn_signature
accounts_nonempty_txn_signature: Option<bool>,

/// Filter by Account Pubkey
#[clap(long)]
accounts_account: Vec<String>,
Expand Down Expand Up @@ -318,6 +321,7 @@ impl Action {
accounts.insert(
"client".to_owned(),
SubscribeRequestFilterAccounts {
nonempty_txn_signature: args.accounts_nonempty_txn_signature,
account: accounts_account,
owner: args.accounts_owner.clone(),
filters,
Expand Down
5 changes: 5 additions & 0 deletions examples/typescript/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ async function subscribeCommand(client, args) {
account: args.accountsAccount,
owner: args.accountsOwner,
filters,
nonemptyTxnSignature: args.accountsNonemptytxnsignature,
};
}

Expand Down Expand Up @@ -321,6 +322,10 @@ function parseCommandLineArgs() {
"filter by lamports, format: `eq:42` / `ne:42` / `lt:42` / `gt:42`",
type: "array",
},
"accounts-nonemptytxnsignature": {
description: "filter by presence of field txn_signature",
type: "boolean",
},
"accounts-dataslice": {
default: [],
describe:
Expand Down
29 changes: 28 additions & 1 deletion yellowstone-grpc-geyser/src/filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,11 +330,13 @@ impl Filter {

#[derive(Debug, Default, Clone)]
struct FilterAccounts {
filters: Vec<(String, FilterAccountsState)>,
nonempty_txn_signature: Vec<(String, Option<bool>)>,
nonempty_txn_signature_required: HashSet<String>,
account: HashMap<Pubkey, HashSet<String>>,
account_required: HashSet<String>,
owner: HashMap<Pubkey, HashSet<String>>,
owner_required: HashSet<String>,
filters: Vec<(String, FilterAccountsState)>,
}

impl FilterAccounts {
Expand All @@ -346,6 +348,12 @@ impl FilterAccounts {

let mut this = Self::default();
for (name, filter) in configs {
this.nonempty_txn_signature
.push((name.clone(), filter.nonempty_txn_signature));
if filter.nonempty_txn_signature.is_some() {
this.nonempty_txn_signature_required.insert(name.clone());
}

ConfigGrpcFilters::check_any(
filter.account.is_empty() && filter.owner.is_empty(),
limit.any,
Expand Down Expand Up @@ -397,6 +405,7 @@ impl FilterAccounts {
message: &'a MessageAccount,
) -> Box<dyn Iterator<Item = (Vec<String>, FilteredMessage<'a>)> + Send + 'a> {
let mut filter = FilterAccountsMatch::new(self);
filter.match_txn_signature(&message.account.txn_signature);
filter.match_account(&message.account.pubkey);
filter.match_owner(&message.account.owner);
filter.match_data_lamports(&message.account.data, message.account.lamports);
Expand Down Expand Up @@ -539,6 +548,7 @@ impl FilterAccountsLamports {
#[derive(Debug)]
pub struct FilterAccountsMatch<'a> {
filter: &'a FilterAccounts,
nonempty_txn_signature: HashSet<&'a str>,
account: HashSet<&'a str>,
owner: HashSet<&'a str>,
data: HashSet<&'a str>,
Expand All @@ -548,6 +558,7 @@ impl<'a> FilterAccountsMatch<'a> {
fn new(filter: &'a FilterAccounts) -> Self {
Self {
filter,
nonempty_txn_signature: Default::default(),
account: Default::default(),
owner: Default::default(),
data: Default::default(),
Expand All @@ -562,6 +573,16 @@ impl<'a> FilterAccountsMatch<'a> {
}
}

pub fn match_txn_signature(&mut self, txn_signature: &Option<Signature>) {
for (name, filter) in self.filter.nonempty_txn_signature.iter() {
if let Some(nonempty_txn_signature) = filter {
if *nonempty_txn_signature == txn_signature.is_some() {
self.nonempty_txn_signature.insert(name);
}
}
}
}

pub fn match_account(&mut self, pubkey: &Pubkey) {
Self::extend(&mut self.account, &self.filter.account, pubkey)
}
Expand All @@ -587,6 +608,11 @@ impl<'a> FilterAccountsMatch<'a> {
let af = &self.filter;

// If filter name in required but not in matched => return `false`
if af.nonempty_txn_signature_required.contains(name)
&& !self.nonempty_txn_signature.contains(name)
{
return None;
}
if af.account_required.contains(name) && !self.account.contains(name) {
return None;
}
Expand Down Expand Up @@ -1156,6 +1182,7 @@ mod tests {
accounts.insert(
"solend".to_owned(),
SubscribeRequestFilterAccounts {
nonempty_txn_signature: None,
account: vec![],
owner: vec![],
filters: vec![],
Expand Down
1 change: 1 addition & 0 deletions yellowstone-grpc-proto/proto/geyser.proto
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ message SubscribeRequestFilterAccounts {
repeated string account = 2;
repeated string owner = 3;
repeated SubscribeRequestFilterAccountsFilter filters = 4;
optional bool nonempty_txn_signature = 5;
}

message SubscribeRequestFilterAccountsFilter {
Expand Down

0 comments on commit 5ac20df

Please sign in to comment.