Check that excess_blob_gas is a multiple of data_gas_per_blob (#7160)

This commit is contained in:
Justin Traglia
2024-03-15 11:46:12 -05:00
committed by GitHub
parent 52d49832d9
commit 94954593ef
4 changed files with 28 additions and 10 deletions

View File

@ -28,8 +28,8 @@ use std::{
time::Instant, time::Instant,
}; };
/// A chain if the blockchain tree, that has functionality to execute blocks and append them to the /// A chain in the blockchain tree that has functionality to execute blocks and append them to
/// it self. /// itself.
#[derive(Clone, Debug, Default, PartialEq, Eq)] #[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct AppendableChain { pub struct AppendableChain {
chain: Chain, chain: Chain,

View File

@ -83,7 +83,7 @@ impl Consensus for BeaconConsensus {
// * difficulty, mix_hash & nonce aka PoW stuff // * difficulty, mix_hash & nonce aka PoW stuff
// low priority as syncing is done in reverse order // low priority as syncing is done in reverse order
// Check if timestamp is in future. Clock can drift but this can be consensus issue. // Check if timestamp is in the future. Clock can drift but this can be consensus issue.
let present_timestamp = let present_timestamp =
SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs(); SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();

View File

@ -15,7 +15,7 @@ pub fn validate_header_standalone(
header: &SealedHeader, header: &SealedHeader,
chain_spec: &ChainSpec, chain_spec: &ChainSpec,
) -> Result<(), ConsensusError> { ) -> Result<(), ConsensusError> {
// Gas used needs to be less then gas limit. Gas used is going to be check after execution. // Gas used needs to be less than gas limit. Gas used is going to be checked after execution.
if header.gas_used > header.gas_limit { if header.gas_used > header.gas_limit {
return Err(ConsensusError::HeaderGasUsedExceedsGasLimit { return Err(ConsensusError::HeaderGasUsedExceedsGasLimit {
gas_used: header.gas_used, gas_used: header.gas_used,
@ -55,7 +55,7 @@ pub fn validate_header_standalone(
Ok(()) Ok(())
} }
/// Validate a transaction in regards to a block header. /// Validate a transaction with regard to a block header.
/// ///
/// The only parameter from the header that affects the transaction is `base_fee`. /// The only parameter from the header that affects the transaction is `base_fee`.
pub fn validate_transaction_regarding_header( pub fn validate_transaction_regarding_header(
@ -248,7 +248,7 @@ pub fn validate_block_standalone(
Ok(()) Ok(())
} }
/// Validate block in regards to chain (parent) /// Validate block with regard to chain (parent)
/// ///
/// Checks: /// Checks:
/// If we already know the block. /// If we already know the block.
@ -282,12 +282,10 @@ pub fn validate_block_regarding_chain<PROV: HeaderProvider + WithdrawalsProvider
/// * `parent_beacon_block_root` exists as a header field /// * `parent_beacon_block_root` exists as a header field
/// * `blob_gas_used` is less than or equal to `MAX_DATA_GAS_PER_BLOCK` /// * `blob_gas_used` is less than or equal to `MAX_DATA_GAS_PER_BLOCK`
/// * `blob_gas_used` is a multiple of `DATA_GAS_PER_BLOB` /// * `blob_gas_used` is a multiple of `DATA_GAS_PER_BLOB`
/// * `excess_blob_gas` is a multiple of `DATA_GAS_PER_BLOB`
pub fn validate_4844_header_standalone(header: &SealedHeader) -> Result<(), ConsensusError> { pub fn validate_4844_header_standalone(header: &SealedHeader) -> Result<(), ConsensusError> {
let blob_gas_used = header.blob_gas_used.ok_or(ConsensusError::BlobGasUsedMissing)?; let blob_gas_used = header.blob_gas_used.ok_or(ConsensusError::BlobGasUsedMissing)?;
let excess_blob_gas = header.excess_blob_gas.ok_or(ConsensusError::ExcessBlobGasMissing)?;
if header.excess_blob_gas.is_none() {
return Err(ConsensusError::ExcessBlobGasMissing)
}
if header.parent_beacon_block_root.is_none() { if header.parent_beacon_block_root.is_none() {
return Err(ConsensusError::ParentBeaconBlockRootMissing) return Err(ConsensusError::ParentBeaconBlockRootMissing)
@ -307,6 +305,15 @@ pub fn validate_4844_header_standalone(header: &SealedHeader) -> Result<(), Cons
}) })
} }
// `excess_blob_gas` must also be a multiple of `DATA_GAS_PER_BLOB`. This will be checked later
// (via `calculate_excess_blob_gas`), but it doesn't hurt to catch the problem sooner.
if excess_blob_gas % DATA_GAS_PER_BLOB != 0 {
return Err(ConsensusError::ExcessBlobGasNotMultipleOfBlobGasPerBlob {
excess_blob_gas,
blob_gas_per_blob: DATA_GAS_PER_BLOB,
})
}
Ok(()) Ok(())
} }

View File

@ -222,6 +222,17 @@ pub enum ConsensusError {
blob_gas_per_blob: u64, blob_gas_per_blob: u64,
}, },
/// Error when excess blob gas is not a multiple of blob gas per blob.
#[error(
"excess blob gas {excess_blob_gas} is not a multiple of blob gas per blob {blob_gas_per_blob}"
)]
ExcessBlobGasNotMultipleOfBlobGasPerBlob {
/// The actual excess blob gas.
excess_blob_gas: u64,
/// The blob gas per blob.
blob_gas_per_blob: u64,
},
/// Error when the blob gas used in the header does not match the expected blob gas used. /// Error when the blob gas used in the header does not match the expected blob gas used.
#[error("blob gas used mismatch: {0}")] #[error("blob gas used mismatch: {0}")]
BlobGasUsedDiff(GotExpected<u64>), BlobGasUsedDiff(GotExpected<u64>),