Rpc: Add custom error for BigTable data not found (#14762)

* Expose not-found bigtable error

* Add custom rpc error for bigtable data not found

* Return custom rpc error when bigtable block is not found

* Generalize long-term storage
This commit is contained in:
Tyera Eulberg 2021-01-21 21:40:47 -07:00 committed by GitHub
parent 12410541a4
commit 71e9958e06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 7 deletions

View File

@ -12,6 +12,7 @@ pub const JSON_RPC_SERVER_ERROR_NODE_UNHEALTHLY: i64 = -32005;
pub const JSON_RPC_SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE: i64 = -32006;
pub const JSON_RPC_SERVER_ERROR_SLOT_SKIPPED: i64 = -32007;
pub const JSON_RPC_SERVER_ERROR_NO_SNAPSHOT: i64 = -32008;
pub const JSON_RPC_SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED: i64 = -32009;
pub enum RpcCustomError {
BlockCleanedUp {
@ -34,6 +35,9 @@ pub enum RpcCustomError {
slot: Slot,
},
NoSnapshot,
LongTermStorageSlotSkipped {
slot: Slot,
},
}
#[derive(Debug, Serialize, Deserialize)]
@ -106,6 +110,11 @@ impl From<RpcCustomError> for Error {
message: "No snapshot".to_string(),
data: None,
},
RpcCustomError::LongTermStorageSlotSkipped { slot } => Self {
code: ErrorCode::ServerError(JSON_RPC_SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED),
message: format!("Slot {} was skipped, or missing in long-term storage", slot),
data: None,
},
}
}
}

View File

@ -670,6 +670,22 @@ impl JsonRpcRequestProcessor {
Ok(())
}
fn check_bigtable_result<T>(
&self,
result: &std::result::Result<T, solana_storage_bigtable::Error>,
) -> Result<()>
where
T: std::fmt::Debug,
{
if result.is_err() {
let err = result.as_ref().unwrap_err();
if let solana_storage_bigtable::Error::BlockNotFound(slot) = err {
return Err(RpcCustomError::LongTermStorageSlotSkipped { slot: *slot }.into());
}
}
Ok(())
}
pub fn get_confirmed_block(
&self,
slot: Slot,
@ -688,9 +704,11 @@ impl JsonRpcRequestProcessor {
self.check_blockstore_root(&result, slot)?;
if result.is_err() {
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
return Ok(self
let bigtable_result = self
.runtime_handle
.block_on(bigtable_ledger_storage.get_confirmed_block(slot))
.block_on(bigtable_ledger_storage.get_confirmed_block(slot));
self.check_bigtable_result(&bigtable_result)?;
return Ok(bigtable_result
.ok()
.map(|confirmed_block| confirmed_block.encode(encoding)));
}
@ -803,9 +821,11 @@ impl JsonRpcRequestProcessor {
self.check_blockstore_root(&result, slot)?;
if result.is_err() || matches!(result, Ok(None)) {
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
return Ok(self
let bigtable_result = self
.runtime_handle
.block_on(bigtable_ledger_storage.get_confirmed_block(slot))
.block_on(bigtable_ledger_storage.get_confirmed_block(slot));
self.check_bigtable_result(&bigtable_result)?;
return Ok(bigtable_result
.ok()
.and_then(|confirmed_block| confirmed_block.block_time));
}

View File

@ -334,7 +334,11 @@ impl LedgerStorage {
"blocks",
slot_to_key(slot),
)
.await?;
.await
.map_err(|err| match err {
bigtable::Error::RowNotFound => Error::BlockNotFound(slot),
_ => err.into(),
})?;
Ok(match block_cell_data {
bigtable::CellData::Bincode(block) => block.into(),
bigtable::CellData::Protobuf(block) => block.try_into().map_err(|_err| {
@ -347,7 +351,11 @@ impl LedgerStorage {
let mut bigtable = self.connection.client();
let transaction_info = bigtable
.get_bincode_cell::<TransactionInfo>("tx", signature.to_string())
.await?;
.await
.map_err(|err| match err {
bigtable::Error::RowNotFound => Error::SignatureNotFound,
_ => err.into(),
})?;
Ok(transaction_info.into())
}
@ -361,7 +369,11 @@ impl LedgerStorage {
// Figure out which block the transaction is located in
let TransactionInfo { slot, index, .. } = bigtable
.get_bincode_cell("tx", signature.to_string())
.await?;
.await
.map_err(|err| match err {
bigtable::Error::RowNotFound => Error::SignatureNotFound,
_ => err.into(),
})?;
// Load the block and return the transaction
let block = self.get_confirmed_block(slot).await?;