Log parsing issue in extract_required_fee_from_log
Description
The extract_required_fee_from_log
function currently makes a best-effort attempt to parse the log returned as part of Celestia's response to a Cosmos transaction when a transaction fails due to insufficient fees. However, it does not handle parsing failures, which can result in a fallback to the original fee-calculation logic without any adjustment. This can lead to repeated failures in fee-submission attempts, creating a potential DOS issue.
Impact
If parsing the log fails, the function falls back to the default logic in calculate_fee
. This can cause an infinite retry loop where the transaction is repeatedly submitted with an insufficient fee, leading to a system hang or a DOS scenario.
/// `log`'s value for this case currently looks like:
/// "insufficient fees; got: 1234utia required: 7980utia: insufficient fee"
/// We'll make a best-effort attempt to parse, but this is just a failsafe to check the
/// new calculated fee using updated Celestia costs is sufficient, so if parsing fails
/// we'll just log the error and otherwise ignore.
fn extract_required_fee_from_log(celestia_broadcast_tx_error_log: &str) -> Option<u64> {
const SUFFIX: &str = "utia: insufficient fee";
// Should be left with e.g. "insufficient fees; got: 1234utia required: 7980".
let Some(log_without_suffix) = celestia_broadcast_tx_error_log.strip_suffix(SUFFIX) else {
warn!(
celestia_broadcast_tx_error_log,
"insufficient gas error doesn't end with '{SUFFIX}'"
);
return None;
};
// Should be left with e.g. "7980".
let Some(required) = log_without_suffix.rsplit(' ').next() else {
warn!(
celestia_broadcast_tx_error_log,
"insufficient gas error doesn't have a space before the required amount"
);
return None;
};
match required.parse::<u64>() {
Ok(required_fee) => {
info!(
required_fee,
"extracted required fee from broadcast transaction response raw log"
);
Some(required_fee)
}
Err(error) => {
warn!(
celestia_broadcast_tx_error_log, %error,
"insufficient gas error required amount cannot be parsed as u64"
);
None
}
}
}
Recommendations
We recommend the following:
Improve the robustness of the log parsing in the
extract_required_fee_from_log
function, such as logging detailed errors and possibly adjusting the fee by a reasonable percentage to avoid repeated failures.Implement more comprehensive tests for fee calculation, including nightly tests to ensure the log-parsing and fee-submission mechanisms are functioning as expected.