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:
parent
12410541a4
commit
71e9958e06
|
@ -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_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE: i64 = -32006;
|
||||||
pub const JSON_RPC_SERVER_ERROR_SLOT_SKIPPED: i64 = -32007;
|
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_NO_SNAPSHOT: i64 = -32008;
|
||||||
|
pub const JSON_RPC_SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED: i64 = -32009;
|
||||||
|
|
||||||
pub enum RpcCustomError {
|
pub enum RpcCustomError {
|
||||||
BlockCleanedUp {
|
BlockCleanedUp {
|
||||||
|
@ -34,6 +35,9 @@ pub enum RpcCustomError {
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
},
|
},
|
||||||
NoSnapshot,
|
NoSnapshot,
|
||||||
|
LongTermStorageSlotSkipped {
|
||||||
|
slot: Slot,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
@ -106,6 +110,11 @@ impl From<RpcCustomError> for Error {
|
||||||
message: "No snapshot".to_string(),
|
message: "No snapshot".to_string(),
|
||||||
data: None,
|
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,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -670,6 +670,22 @@ impl JsonRpcRequestProcessor {
|
||||||
Ok(())
|
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(
|
pub fn get_confirmed_block(
|
||||||
&self,
|
&self,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
|
@ -688,9 +704,11 @@ impl JsonRpcRequestProcessor {
|
||||||
self.check_blockstore_root(&result, slot)?;
|
self.check_blockstore_root(&result, slot)?;
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
|
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
|
||||||
return Ok(self
|
let bigtable_result = self
|
||||||
.runtime_handle
|
.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()
|
.ok()
|
||||||
.map(|confirmed_block| confirmed_block.encode(encoding)));
|
.map(|confirmed_block| confirmed_block.encode(encoding)));
|
||||||
}
|
}
|
||||||
|
@ -803,9 +821,11 @@ impl JsonRpcRequestProcessor {
|
||||||
self.check_blockstore_root(&result, slot)?;
|
self.check_blockstore_root(&result, slot)?;
|
||||||
if result.is_err() || matches!(result, Ok(None)) {
|
if result.is_err() || matches!(result, Ok(None)) {
|
||||||
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
|
if let Some(bigtable_ledger_storage) = &self.bigtable_ledger_storage {
|
||||||
return Ok(self
|
let bigtable_result = self
|
||||||
.runtime_handle
|
.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()
|
.ok()
|
||||||
.and_then(|confirmed_block| confirmed_block.block_time));
|
.and_then(|confirmed_block| confirmed_block.block_time));
|
||||||
}
|
}
|
||||||
|
|
|
@ -334,7 +334,11 @@ impl LedgerStorage {
|
||||||
"blocks",
|
"blocks",
|
||||||
slot_to_key(slot),
|
slot_to_key(slot),
|
||||||
)
|
)
|
||||||
.await?;
|
.await
|
||||||
|
.map_err(|err| match err {
|
||||||
|
bigtable::Error::RowNotFound => Error::BlockNotFound(slot),
|
||||||
|
_ => err.into(),
|
||||||
|
})?;
|
||||||
Ok(match block_cell_data {
|
Ok(match block_cell_data {
|
||||||
bigtable::CellData::Bincode(block) => block.into(),
|
bigtable::CellData::Bincode(block) => block.into(),
|
||||||
bigtable::CellData::Protobuf(block) => block.try_into().map_err(|_err| {
|
bigtable::CellData::Protobuf(block) => block.try_into().map_err(|_err| {
|
||||||
|
@ -347,7 +351,11 @@ impl LedgerStorage {
|
||||||
let mut bigtable = self.connection.client();
|
let mut bigtable = self.connection.client();
|
||||||
let transaction_info = bigtable
|
let transaction_info = bigtable
|
||||||
.get_bincode_cell::<TransactionInfo>("tx", signature.to_string())
|
.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())
|
Ok(transaction_info.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +369,11 @@ impl LedgerStorage {
|
||||||
// Figure out which block the transaction is located in
|
// Figure out which block the transaction is located in
|
||||||
let TransactionInfo { slot, index, .. } = bigtable
|
let TransactionInfo { slot, index, .. } = bigtable
|
||||||
.get_bincode_cell("tx", signature.to_string())
|
.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
|
// Load the block and return the transaction
|
||||||
let block = self.get_confirmed_block(slot).await?;
|
let block = self.get_confirmed_block(slot).await?;
|
||||||
|
|
Loading…
Reference in New Issue