geyser: support data_slice for accounts (#150)

This commit is contained in:
Kirill Fomichev 2023-06-28 23:50:57 -04:00 committed by GitHub
parent b73848a37a
commit ef9c079f07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 227 additions and 120 deletions

View File

@ -5,6 +5,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: arduino/setup-protoc@v2
# Setup .npmrc file to publish to npm
- uses: actions/setup-node@v3
with:

View File

@ -34,6 +34,16 @@ jobs:
profile: minimal
components: rustfmt
- uses: actions/cache@v3
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
yellowstone-grpc/target/
key: cargo-${{ hashFiles('rust-toolchain.toml') }}-${{ hashFiles('**/Cargo.lock') }}-0001
- name: Check Solana version
run: |
echo "CI_TAG=$(ci/getTag.sh)" >> "$GITHUB_ENV"
@ -50,6 +60,7 @@ jobs:
run: ./ci/create-tarball.sh
- name: Release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v1
with:
tag_name: ${{ env.BUILD_NAME }}

View File

@ -1,6 +1,3 @@
# Source:
# https://github.com/solana-labs/solana-accountsdb-plugin-postgres/blob/master/.github/workflows/test.yml
on:
workflow_dispatch:
push:
@ -33,12 +30,15 @@ jobs:
profile: minimal
components: rustfmt, clippy
- uses: actions/cache@v2
- uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
key: cargo-build-${{ hashFiles('**/Cargo.lock') }}-${{ env.RUST_STABLE}}
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
yellowstone-grpc/target/
key: cargo-${{ hashFiles('rust-toolchain.toml') }}-${{ hashFiles('**/Cargo.lock') }}-0001
- name: cargo tree
run: |

View File

@ -14,71 +14,48 @@ The minor version will be incremented upon a breaking change and the patch versi
### Fixes
### Breaking
## 2023-06-29
- @triton-one/yellowstone-grpc:0.1.2
- yellowstone-grpc-client-1.4.0+solana.1.16.1
- yellowstone-grpc-geyser-1.0.0+solana.1.16.1
- yellowstone-grpc-proto-1.4.0+solana.1.16.1
### Features
- geyser: support data_slice for accounts ([#150](https://github.com/rpcpool/yellowstone-grpc/pull/150)).
- client: add TypeScript client ([#142](https://github.com/rpcpool/yellowstone-grpc/pull/142)).
### Fixes
- client: set max message size for decode ([#151](https://github.com/rpcpool/yellowstone-grpc/pull/151)).
- geyser: remove duplicated account updates for confirmed/finalized ([#152](https://github.com/rpcpool/yellowstone-grpc/pull/152)).
### Breaking
## 2023-06-16
## [yellowstone-grpc-proto-1.3.0+solana.1.16.1] - 2023-06-16
- yellowstone-grpc-client-1.3.0+solana.1.16.1
- yellowstone-grpc-geyser-0.8.2+solana.1.16.1
- yellowstone-grpc-proto-1.3.0+solana.1.16.1
### Features
- geyser: update solana =1.16.1 ([#146](https://github.com/rpcpool/yellowstone-grpc/pull/146)).
### Fixes
## 2023-06-15
### Breaking
## [yellowstone-grpc-client-1.3.0+solana.1.16.1] - 2023-06-16
### Features
- geyser: update solana =1.16.1 ([#146](https://github.com/rpcpool/yellowstone-grpc/pull/146)).
### Fixes
### Breaking
## [yellowstone-grpc-geyser-0.8.2+solana.1.16.1] - 2023-06-16
### Features
- geyser: update solana =1.16.1 ([#146](https://github.com/rpcpool/yellowstone-grpc/pull/146)).
### Fixes
### Breaking
## [yellowstone-grpc-proto-1.3.0+solana.1.15.2] - 2023-06-15
### Features
- geyser: Update `tonic`, `0.8.2` => `0.9.2` ([#145](https://github.com/rpcpool/yellowstone-grpc/pull/145)).
### Fixes
### Breaking
## [yellowstone-grpc-client-1.3.0+solana.1.15.2] - 2023-06-15
- yellowstone-grpc-client-1.3.0+solana.1.14.18
- yellowstone-grpc-client-1.3.0+solana.1.15.2
- yellowstone-grpc-geyser-0.8.2+solana.1.14.18
- yellowstone-grpc-geyser-0.8.2+solana.1.15.2
- yellowstone-grpc-proto-1.3.0+solana.1.14.18
- yellowstone-grpc-proto-1.3.0+solana.1.15.2
### Features
- geyser: Update `tonic`, `0.8.2` => `0.9.2` ([#145](https://github.com/rpcpool/yellowstone-grpc/pull/145)).
- geyser: Add methods `health_check` and `health_watch` ([#145](https://github.com/rpcpool/yellowstone-grpc/pull/145)).
### Fixes
### Breaking
## [yellowstone-grpc-geyser-0.8.2+solana.1.15.2] - 2023-06-15
### Features
- geyser: Add prometheus metric `message_queue_size` ([#145](https://github.com/rpcpool/yellowstone-grpc/pull/145)).
- geyser: Update `tonic`, `0.8.2` => `0.9.2` ([#145](https://github.com/rpcpool/yellowstone-grpc/pull/145)).
- geyser: Send task per connection ([#145](https://github.com/rpcpool/yellowstone-grpc/pull/145)).
- geyser: Send processed immediately without `Slot` message ([#145](https://github.com/rpcpool/yellowstone-grpc/pull/145)).
### Fixes
### Breaking

8
Cargo.lock generated
View File

@ -4125,7 +4125,7 @@ dependencies = [
[[package]]
name = "yellowstone-grpc-client"
version = "1.3.0+solana.1.16.1"
version = "1.4.0+solana.1.16.1"
dependencies = [
"bytes",
"futures",
@ -4139,7 +4139,7 @@ dependencies = [
[[package]]
name = "yellowstone-grpc-client-simple"
version = "1.3.0+solana.1.16.1"
version = "1.4.0+solana.1.16.1"
dependencies = [
"anyhow",
"backoff",
@ -4157,7 +4157,7 @@ dependencies = [
[[package]]
name = "yellowstone-grpc-geyser"
version = "0.8.2+solana.1.16.1"
version = "1.0.0+solana.1.16.1"
dependencies = [
"anyhow",
"base64 0.21.2",
@ -4187,7 +4187,7 @@ dependencies = [
[[package]]
name = "yellowstone-grpc-proto"
version = "1.3.0+solana.1.16.1"
version = "1.4.0+solana.1.16.1"
dependencies = [
"anyhow",
"prost",

View File

@ -1,9 +1,9 @@
[workspace]
members = [
"examples/rust", # 1.3.0+solana.1.16.1
"yellowstone-grpc-client", # 1.3.0+solana.1.16.1
"yellowstone-grpc-geyser", # 0.8.2+solana.1.16.1
"yellowstone-grpc-proto", # 1.3.0+solana.1.16.1
"examples/rust", # 1.4.0+solana.1.16.1
"yellowstone-grpc-client", # 1.4.0+solana.1.16.1
"yellowstone-grpc-geyser", # 1.0.0+solana.1.16.1
"yellowstone-grpc-proto", # 1.4.0+solana.1.16.1
]
[profile.release]

View File

@ -1,6 +1,6 @@
[package]
name = "yellowstone-grpc-client-simple"
version = "1.3.0+solana.1.16.1"
version = "1.4.0+solana.1.16.1"
authors = ["Triton One"]
edition = "2021"
publish = false

View File

@ -11,10 +11,11 @@ use {
subscribe_request_filter_accounts_filter::Filter as AccountsFilterDataOneof,
subscribe_request_filter_accounts_filter_memcmp::Data as AccountsFilterMemcmpOneof,
subscribe_update::UpdateOneof, CommitmentLevel, SubscribeRequest,
SubscribeRequestFilterAccounts, SubscribeRequestFilterAccountsFilter,
SubscribeRequestFilterAccountsFilterMemcmp, SubscribeRequestFilterBlocks,
SubscribeRequestFilterBlocksMeta, SubscribeRequestFilterSlots,
SubscribeRequestFilterTransactions, SubscribeUpdateAccount,
SubscribeRequestAccountsDataSlice, SubscribeRequestFilterAccounts,
SubscribeRequestFilterAccountsFilter, SubscribeRequestFilterAccountsFilterMemcmp,
SubscribeRequestFilterBlocks, SubscribeRequestFilterBlocksMeta,
SubscribeRequestFilterSlots, SubscribeRequestFilterTransactions,
SubscribeUpdateAccount,
},
tonic::service::Interceptor,
},
@ -109,6 +110,10 @@ struct ActionSubscribe {
#[clap(long)]
accounts_datasize: Option<u64>,
/// Receive only part of updated data account, format: `offset,size`
#[clap(long)]
accounts_data_slice: Vec<String>,
/// Subscribe on slots updates
#[clap(long)]
slots: bool,
@ -229,6 +234,20 @@ impl Action {
blocks_meta.insert("client".to_owned(), SubscribeRequestFilterBlocksMeta {});
}
let mut accounts_data_slice = Vec::new();
for data_slice in args.accounts_data_slice.iter() {
match data_slice.split_once(',') {
Some((offset, length)) => match (offset.parse(), length.parse()) {
(Ok(offset), Ok(length)) => {
accounts_data_slice
.push(SubscribeRequestAccountsDataSlice { offset, length });
}
_ => anyhow::bail!("invalid data_slice"),
},
_ => anyhow::bail!("invalid data_slice"),
}
}
Some((
SubscribeRequest {
slots,
@ -237,6 +256,7 @@ impl Action {
blocks,
blocks_meta,
commitment: commitment.map(|x| x as i32),
accounts_data_slice,
},
args.resub.unwrap_or(0),
))
@ -421,6 +441,7 @@ async fn geyser_subscribe(
blocks: HashMap::default(),
blocks_meta: HashMap::default(),
commitment: None,
accounts_data_slice: Vec::default(),
})
.await
.map_err(GeyserGrpcClientError::SubscribeSendError)?;

View File

@ -90,6 +90,7 @@ async function subscribeCommand(client, args) {
transactions: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
};
if (args.accounts) {
const filters: SubscribeRequestFilterAccountsFilter[] = [];
@ -142,6 +143,21 @@ async function subscribeCommand(client, args) {
request.blocksMeta.client = {};
}
if (args.accounts.dataslice) {
for (let filter in args.accounts.dataslice) {
const filterSpec = filter.split(",", 1);
if (filterSpec.length != 2) {
throw new Error("invalid data slice");
}
const [offset, length] = filterSpec;
request.accountsDataSlice.push({
offset: parseInt(offset, 10),
length: parseInt(length, 10),
});
}
}
// Send subscribe request
await new Promise<void>((resolve, reject) => {
stream.write(request, (err) => {
@ -222,6 +238,12 @@ function parseCommandLineArgs() {
describe: "filter by data size",
type: "number",
},
"accounts-dataslice": {
default: [],
describe:
"receive only part of updated data account, format: `offset,size`",
type: "string",
},
slots: {
default: false,
describe: "subscribe on slots updates",

View File

@ -1 +0,0 @@
node_modules

View File

@ -1,6 +1,6 @@
{
"name": "@triton-one/yellowstone-grpc",
"version": "0.1.1",
"version": "0.1.2",
"license": "Apache-2.0",
"author": "Triton One",
"description": "Yellowstone gRPC Geyser Node.js Client",
@ -31,5 +31,6 @@
"prettier": "2.8.3",
"ts-proto": "^1.139.0",
"typescript": "^4.9.5"
}
},
"files": ["dist"]
}

View File

@ -8,6 +8,7 @@ import {
GetLatestBlockhashResponse,
GeyserClient,
IsBlockhashValidResponse,
SubscribeRequestAccountsDataSlice,
SubscribeRequestFilterAccounts,
SubscribeRequestFilterBlocks,
SubscribeRequestFilterBlocksMeta,
@ -81,7 +82,8 @@ export default class Client {
transactions: { [key: string]: SubscribeRequestFilterTransactions },
blocks: { [key: string]: SubscribeRequestFilterBlocks },
blocksMeta: { [key: string]: SubscribeRequestFilterBlocksMeta },
commitment?: CommitmentLevel | undefined
commitment: CommitmentLevel | undefined,
accountsDataSlice: SubscribeRequestAccountsDataSlice[]
) {
const stream = await this._client.subscribe();
@ -94,6 +96,7 @@ export default class Client {
blocks,
blocksMeta,
commitment,
accountsDataSlice,
},
(err) => {
if (err === null || err === undefined) {

View File

@ -1,6 +1,6 @@
[package]
name = "yellowstone-grpc-client"
version = "1.3.0+solana.1.16.1"
version = "1.4.0+solana.1.16.1"
authors = ["Triton One"]
edition = "2021"
description = "Yellowstone gRPC Geyser Simple Client"
@ -16,7 +16,7 @@ http = "0.2.8"
thiserror = "1.0"
tonic = { version = "0.9.2", features = ["gzip", "tls", "tls-roots"] }
tonic-health = "0.9.2"
yellowstone-grpc-proto = { path = "../yellowstone-grpc-proto", version = "1.3.0+solana.1.16.1" }
yellowstone-grpc-proto = { path = "../yellowstone-grpc-proto", version = "1.4.0+solana.1.16.1" }
[dev-dependencies]
tokio = { version = "1.21.2", features = ["macros"] }

View File

@ -20,9 +20,9 @@ use {
GetBlockHeightResponse, GetLatestBlockhashRequest, GetLatestBlockhashResponse,
GetSlotRequest, GetSlotResponse, GetVersionRequest, GetVersionResponse,
IsBlockhashValidRequest, IsBlockhashValidResponse, PingRequest, PongResponse,
SubscribeRequest, SubscribeRequestFilterAccounts, SubscribeRequestFilterBlocks,
SubscribeRequestFilterBlocksMeta, SubscribeRequestFilterSlots,
SubscribeRequestFilterTransactions, SubscribeUpdate,
SubscribeRequest, SubscribeRequestAccountsDataSlice, SubscribeRequestFilterAccounts,
SubscribeRequestFilterBlocks, SubscribeRequestFilterBlocksMeta,
SubscribeRequestFilterSlots, SubscribeRequestFilterTransactions, SubscribeUpdate,
},
};
@ -133,6 +133,7 @@ impl<F: Interceptor> GeyserGrpcClient<F> {
Ok((subscribe_tx, response.into_inner()))
}
#[allow(clippy::too_many_arguments)]
pub async fn subscribe_once(
&mut self,
slots: HashMap<String, SubscribeRequestFilterSlots>,
@ -141,6 +142,7 @@ impl<F: Interceptor> GeyserGrpcClient<F> {
blocks: HashMap<String, SubscribeRequestFilterBlocks>,
blocks_meta: HashMap<String, SubscribeRequestFilterBlocksMeta>,
commitment: Option<CommitmentLevel>,
accounts_data_slice: Vec<SubscribeRequestAccountsDataSlice>,
) -> GeyserGrpcClientResult<impl Stream<Item = Result<SubscribeUpdate, Status>>> {
let (mut subscribe_tx, response) = self.subscribe().await?;
subscribe_tx
@ -151,6 +153,7 @@ impl<F: Interceptor> GeyserGrpcClient<F> {
blocks,
blocks_meta,
commitment: commitment.map(|value| value as i32),
accounts_data_slice,
})
.await?;
Ok(response)

View File

@ -1,6 +1,6 @@
[package]
name = "yellowstone-grpc-geyser"
version = "0.8.2+solana.1.16.1"
version = "1.0.0+solana.1.16.1"
authors = ["Triton One"]
edition = "2021"
description = "Yellowstone gRPC Geyser Plugin"

View File

@ -11,10 +11,10 @@ use {
proto::{
subscribe_request_filter_accounts_filter::Filter as AccountsFilterDataOneof,
subscribe_request_filter_accounts_filter_memcmp::Data as AccountsFilterMemcmpOneof,
CommitmentLevel, SubscribeRequest, SubscribeRequestFilterAccounts,
SubscribeRequestFilterAccountsFilter, SubscribeRequestFilterBlocks,
SubscribeRequestFilterBlocksMeta, SubscribeRequestFilterSlots,
SubscribeRequestFilterTransactions, SubscribeUpdate,
CommitmentLevel, SubscribeRequest, SubscribeRequestAccountsDataSlice,
SubscribeRequestFilterAccounts, SubscribeRequestFilterAccountsFilter,
SubscribeRequestFilterBlocks, SubscribeRequestFilterBlocksMeta,
SubscribeRequestFilterSlots, SubscribeRequestFilterTransactions, SubscribeUpdate,
},
},
base64::{engine::general_purpose::STANDARD as base64_engine, Engine},
@ -34,6 +34,7 @@ pub struct Filter {
blocks: FilterBlocks,
blocks_meta: FilterBlocksMeta,
commitment: CommitmentLevel,
accounts_data_slice: Vec<FilterAccountsDataSlice>,
}
impl Filter {
@ -45,6 +46,7 @@ impl Filter {
blocks: FilterBlocks::new(&config.blocks, &limit.blocks)?,
blocks_meta: FilterBlocksMeta::new(&config.blocks_meta, &limit.blocks_meta)?,
commitment: Self::decode_commitment(config.commitment)?,
accounts_data_slice: FilterAccountsDataSlice::create(&config.accounts_data_slice)?,
})
}
@ -91,7 +93,7 @@ impl Filter {
} else {
Some(SubscribeUpdate {
filters,
update_oneof: Some(message.into()),
update_oneof: Some(message.to_proto(&self.accounts_data_slice)),
})
}
}
@ -538,6 +540,43 @@ impl FilterBlocksMeta {
}
}
#[derive(Debug, Clone, Copy)]
pub struct FilterAccountsDataSlice {
pub start: usize,
pub end: usize,
pub length: usize,
}
impl From<&SubscribeRequestAccountsDataSlice> for FilterAccountsDataSlice {
fn from(data_slice: &SubscribeRequestAccountsDataSlice) -> Self {
Self {
start: data_slice.offset as usize,
end: (data_slice.offset + data_slice.length) as usize,
length: data_slice.length as usize,
}
}
}
impl FilterAccountsDataSlice {
pub fn create(slices: &[SubscribeRequestAccountsDataSlice]) -> anyhow::Result<Vec<Self>> {
let slices = slices.iter().map(Into::into).collect::<Vec<Self>>();
for (i, slice_a) in slices.iter().enumerate() {
// check order
for slice_b in slices[i + 1..].iter() {
anyhow::ensure!(slice_a.start <= slice_b.start, "data slices out of order");
}
// check overlap
for slice_b in slices[0..i].iter() {
anyhow::ensure!(slice_a.start >= slice_b.end, "data slices overlap");
}
}
Ok(slices)
}
}
#[cfg(test)]
mod tests {
use {
@ -614,6 +653,7 @@ mod tests {
blocks: HashMap::new(),
blocks_meta: HashMap::new(),
commitment: None,
accounts_data_slice: Vec::new(),
};
let limit = ConfigGrpcFilters::default();
let filter = Filter::new(&config, &limit);
@ -640,6 +680,7 @@ mod tests {
blocks: HashMap::new(),
blocks_meta: HashMap::new(),
commitment: None,
accounts_data_slice: Vec::new(),
};
let mut limit = ConfigGrpcFilters::default();
limit.accounts.any = false;
@ -671,6 +712,7 @@ mod tests {
blocks: HashMap::new(),
blocks_meta: HashMap::new(),
commitment: None,
accounts_data_slice: Vec::new(),
};
let mut limit = ConfigGrpcFilters::default();
limit.transactions.any = false;
@ -701,6 +743,7 @@ mod tests {
blocks: HashMap::new(),
blocks_meta: HashMap::new(),
commitment: None,
accounts_data_slice: Vec::new(),
};
let mut limit = ConfigGrpcFilters::default();
limit.transactions.any = false;
@ -737,6 +780,7 @@ mod tests {
blocks: HashMap::new(),
blocks_meta: HashMap::new(),
commitment: None,
accounts_data_slice: Vec::new(),
};
let limit = ConfigGrpcFilters::default();
let filter = Filter::new(&config, &limit).unwrap();
@ -776,6 +820,7 @@ mod tests {
blocks: HashMap::new(),
blocks_meta: HashMap::new(),
commitment: None,
accounts_data_slice: Vec::new(),
};
let limit = ConfigGrpcFilters::default();
let filter = Filter::new(&config, &limit).unwrap();
@ -815,6 +860,7 @@ mod tests {
blocks: HashMap::new(),
blocks_meta: HashMap::new(),
commitment: None,
accounts_data_slice: Vec::new(),
};
let limit = ConfigGrpcFilters::default();
let filter = Filter::new(&config, &limit).unwrap();
@ -860,6 +906,7 @@ mod tests {
blocks: HashMap::new(),
blocks_meta: HashMap::new(),
commitment: None,
accounts_data_slice: Vec::new(),
};
let limit = ConfigGrpcFilters::default();
let filter = Filter::new(&config, &limit).unwrap();
@ -907,6 +954,7 @@ mod tests {
blocks: HashMap::new(),
blocks_meta: HashMap::new(),
commitment: None,
accounts_data_slice: Vec::new(),
};
let limit = ConfigGrpcFilters::default();
let filter = Filter::new(&config, &limit).unwrap();

View File

@ -1,7 +1,7 @@
use {
crate::{
config::ConfigGrpc,
filters::Filter,
filters::{Filter, FilterAccountsDataSlice},
prom::{CONNECTIONS_TOTAL, INVALID_FULL_BLOCKS, MESSAGE_QUEUE_SIZE},
proto::{
self,
@ -213,33 +213,59 @@ pub enum Message {
BlockMeta(MessageBlockMeta),
}
impl From<&Message> for UpdateOneof {
fn from(message: &Message) -> Self {
match message {
Message::Slot(message) => UpdateOneof::Slot(SubscribeUpdateSlot {
impl Message {
pub const fn get_slot(&self) -> u64 {
match self {
Self::Slot(msg) => msg.slot,
Self::Account(msg) => msg.slot,
Self::Transaction(msg) => msg.slot,
Self::Block(msg) => msg.slot,
Self::BlockMeta(msg) => msg.slot,
}
}
pub fn to_proto(&self, accounts_data_slice: &[FilterAccountsDataSlice]) -> UpdateOneof {
match self {
Self::Slot(message) => UpdateOneof::Slot(SubscribeUpdateSlot {
slot: message.slot,
parent: message.parent,
status: message.status as i32,
}),
Message::Account(message) => UpdateOneof::Account(SubscribeUpdateAccount {
account: Some(SubscribeUpdateAccountInfo {
pubkey: message.account.pubkey.as_ref().into(),
lamports: message.account.lamports,
owner: message.account.owner.as_ref().into(),
executable: message.account.executable,
rent_epoch: message.account.rent_epoch,
data: message.account.data.clone(),
write_version: message.account.write_version,
txn_signature: message.account.txn_signature.map(|s| s.as_ref().into()),
}),
slot: message.slot,
is_startup: message.is_startup,
}),
Message::Transaction(message) => UpdateOneof::Transaction(SubscribeUpdateTransaction {
Self::Account(message) => {
let data = if accounts_data_slice.is_empty() {
message.account.data.clone()
} else {
let mut data =
Vec::with_capacity(accounts_data_slice.iter().map(|ds| ds.length).sum());
for data_slice in accounts_data_slice {
if message.account.data.len() >= data_slice.end {
data.extend_from_slice(
&message.account.data[data_slice.start..data_slice.end],
);
}
}
data
};
UpdateOneof::Account(SubscribeUpdateAccount {
account: Some(SubscribeUpdateAccountInfo {
pubkey: message.account.pubkey.as_ref().into(),
lamports: message.account.lamports,
owner: message.account.owner.as_ref().into(),
executable: message.account.executable,
rent_epoch: message.account.rent_epoch,
data,
write_version: message.account.write_version,
txn_signature: message.account.txn_signature.map(|s| s.as_ref().into()),
}),
slot: message.slot,
is_startup: message.is_startup,
})
}
Self::Transaction(message) => UpdateOneof::Transaction(SubscribeUpdateTransaction {
transaction: Some((&message.transaction).into()),
slot: message.slot,
}),
Message::Block(message) => UpdateOneof::Block(SubscribeUpdateBlock {
Self::Block(message) => UpdateOneof::Block(SubscribeUpdateBlock {
slot: message.slot,
blockhash: message.blockhash.clone(),
rewards: Some(proto::convert::create_rewards(message.rewards.as_slice())),
@ -251,7 +277,7 @@ impl From<&Message> for UpdateOneof {
parent_slot: message.parent_slot,
parent_blockhash: message.parent_blockhash.clone(),
}),
Message::BlockMeta(message) => UpdateOneof::BlockMeta(SubscribeUpdateBlockMeta {
Self::BlockMeta(message) => UpdateOneof::BlockMeta(SubscribeUpdateBlockMeta {
slot: message.slot,
blockhash: message.blockhash.clone(),
rewards: Some(proto::convert::create_rewards(message.rewards.as_slice())),
@ -267,18 +293,6 @@ impl From<&Message> for UpdateOneof {
}
}
impl Message {
pub const fn get_slot(&self) -> u64 {
match self {
Self::Slot(msg) => msg.slot,
Self::Account(msg) => msg.slot,
Self::Transaction(msg) => msg.slot,
Self::Block(msg) => msg.slot,
Self::BlockMeta(msg) => msg.slot,
}
}
}
#[derive(Debug)]
struct BlockhashStatus {
slot: u64,
@ -752,6 +766,7 @@ impl Geyser for GrpcService {
blocks: HashMap::new(),
blocks_meta: HashMap::new(),
commitment: None,
accounts_data_slice: Vec::new(),
},
&self.config.filters,
)

View File

@ -1,6 +1,6 @@
[package]
name = "yellowstone-grpc-proto"
version = "1.3.0+solana.1.16.1"
version = "1.4.0+solana.1.16.1"
authors = ["Triton One"]
edition = "2021"
description = "Yellowstone gRPC Geyser Protobuf Definitions"

View File

@ -29,6 +29,7 @@ message SubscribeRequest {
map<string, SubscribeRequestFilterBlocks> blocks = 4;
map<string, SubscribeRequestFilterBlocksMeta> blocks_meta = 5;
optional CommitmentLevel commitment = 6;
repeated SubscribeRequestAccountsDataSlice accounts_data_slice = 7;
}
message SubscribeRequestFilterAccounts {
@ -68,6 +69,11 @@ message SubscribeRequestFilterBlocks {}
message SubscribeRequestFilterBlocksMeta {}
message SubscribeRequestAccountsDataSlice {
uint64 offset = 1;
uint64 length = 2;
}
message SubscribeUpdate {
repeated string filters = 1;
oneof update_oneof {