check byte length when converting to uint256 and hash256 from bytes. Add comments

This commit is contained in:
realbigsean 2023-02-08 10:38:45 -05:00
parent 8661477675
commit dd40adc5c0
No known key found for this signature in database
GPG Key ID: BE1B3DB104F6C788

View File

@ -2040,6 +2040,10 @@ pub enum BlobTxConversionError {
SerdeJson(serde_json::Error), SerdeJson(serde_json::Error),
/// There was an error converting the transaction from hex. /// There was an error converting the transaction from hex.
FromHexError(String), FromHexError(String),
/// The `max_fee_per_data_gas` field did not contains 32 bytes.
InvalidDataGasBytesLen,
/// A `versioned_hash` did not contain 32 bytes.
InvalidVersionedHashBytesLen,
} }
impl From<ssz_types::Error> for BlobTxConversionError { impl From<ssz_types::Error> for BlobTxConversionError {
@ -2064,29 +2068,49 @@ fn ethers_tx_to_bytes<T: EthSpec>(
.transaction_type .transaction_type
.ok_or(BlobTxConversionError::NoTransactionType)? .ok_or(BlobTxConversionError::NoTransactionType)?
.as_u64(); .as_u64();
let tx = if BLOB_TX_TYPE as u64 == tx_type { let tx = if BLOB_TX_TYPE as u64 == tx_type {
// ******************** BlobTransaction fields ********************
// chainId
let chain_id = transaction let chain_id = transaction
.chain_id .chain_id
.ok_or(BlobTxConversionError::NoChainId)?; .ok_or(BlobTxConversionError::NoChainId)?;
// nonce
let nonce = if transaction.nonce > Uint256::from(u64::MAX) { let nonce = if transaction.nonce > Uint256::from(u64::MAX) {
return Err(BlobTxConversionError::NonceTooLarge); return Err(BlobTxConversionError::NonceTooLarge);
} else { } else {
transaction.nonce.as_u64() transaction.nonce.as_u64()
}; };
// maxPriorityFeePerGas
let max_priority_fee_per_gas = transaction let max_priority_fee_per_gas = transaction
.max_priority_fee_per_gas .max_priority_fee_per_gas
.ok_or(BlobTxConversionError::MaxPriorityFeePerGasMissing)?; .ok_or(BlobTxConversionError::MaxPriorityFeePerGasMissing)?;
// maxFeePerGas
let max_fee_per_gas = transaction let max_fee_per_gas = transaction
.max_fee_per_gas .max_fee_per_gas
.ok_or(BlobTxConversionError::MaxFeePerGasMissing)?; .ok_or(BlobTxConversionError::MaxFeePerGasMissing)?;
// gas
let gas = if transaction.gas > Uint256::from(u64::MAX) { let gas = if transaction.gas > Uint256::from(u64::MAX) {
return Err(BlobTxConversionError::GasTooHigh); return Err(BlobTxConversionError::GasTooHigh);
} else { } else {
transaction.gas.as_u64() transaction.gas.as_u64()
}; };
// to
let to = transaction.to; let to = transaction.to;
// value
let value = transaction.value; let value = transaction.value;
// data (a.k.a input)
let data = VariableList::new(transaction.input.to_vec())?; let data = VariableList::new(transaction.input.to_vec())?;
// accessList
let access_list = VariableList::new( let access_list = VariableList::new(
transaction transaction
.access_list .access_list
@ -2102,17 +2126,29 @@ fn ethers_tx_to_bytes<T: EthSpec>(
}) })
.collect::<Result<Vec<AccessTuple>, BlobTxConversionError>>()?, .collect::<Result<Vec<AccessTuple>, BlobTxConversionError>>()?,
)?; )?;
let max_fee_per_data_gas = Uint256::from_big_endian(
&eth2_serde_utils::hex::decode( // ******************** BlobTransaction `other` fields ********************
transaction //
.other // Here we use the `other` field in the `ethers-rs` `Transaction` type because
.get("maxFeePerDataGas") // `ethers-rs` does not yet support SSZ and therefore the blobs transaction type.
.ok_or(BlobTxConversionError::MaxFeePerDataGasMissing)?
.as_str() // maxFeePerDataGas
.ok_or(BlobTxConversionError::MaxFeePerDataGasMissing)?, let data_gas_bytes = eth2_serde_utils::hex::decode(
) transaction
.map_err(BlobTxConversionError::FromHexError)?, .other
); .get("maxFeePerDataGas")
.ok_or(BlobTxConversionError::MaxFeePerDataGasMissing)?
.as_str()
.ok_or(BlobTxConversionError::MaxFeePerDataGasMissing)?,
)
.map_err(BlobTxConversionError::FromHexError)?;
let max_fee_per_data_gas = if data_gas_bytes.len() != Uint256::ssz_fixed_len() {
Err(BlobTxConversionError::InvalidDataGasBytesLen)
} else {
Ok(Uint256::from_big_endian(&data_gas_bytes))
}?;
// blobVersionedHashes
let blob_versioned_hashes = transaction let blob_versioned_hashes = transaction
.other .other
.get("blobVersionedHashes") .get("blobVersionedHashes")
@ -2121,14 +2157,17 @@ fn ethers_tx_to_bytes<T: EthSpec>(
.ok_or(BlobTxConversionError::BlobVersionedHashesMissing)? .ok_or(BlobTxConversionError::BlobVersionedHashesMissing)?
.into_iter() .into_iter()
.map(|versioned_hash| { .map(|versioned_hash| {
Ok(Hash256::from_slice( let hash_bytes = eth2_serde_utils::hex::decode(
&eth2_serde_utils::hex::decode( versioned_hash
versioned_hash .as_str()
.as_str() .ok_or(BlobTxConversionError::BlobVersionedHashesMissing)?,
.ok_or(BlobTxConversionError::BlobVersionedHashesMissing)?, )
) .map_err(BlobTxConversionError::FromHexError)?;
.map_err(BlobTxConversionError::FromHexError)?, if hash_bytes.len() != Hash256::ssz_fixed_len() {
)) Err(BlobTxConversionError::InvalidVersionedHashBytesLen)
} else {
Ok(Hash256::from_slice(&hash_bytes))
}
}) })
.collect::<Result<Vec<VersionedHash>, BlobTxConversionError>>()?; .collect::<Result<Vec<VersionedHash>, BlobTxConversionError>>()?;
let message = BlobTransaction { let message = BlobTransaction {
@ -2145,6 +2184,8 @@ fn ethers_tx_to_bytes<T: EthSpec>(
blob_versioned_hashes: VariableList::new(blob_versioned_hashes)?, blob_versioned_hashes: VariableList::new(blob_versioned_hashes)?,
}; };
// ******************** EcdsaSignature fields ********************
let y_parity = if transaction.v == U64::zero() { let y_parity = if transaction.v == U64::zero() {
false false
} else if transaction.v == U64::one() { } else if transaction.v == U64::one() {
@ -2156,6 +2197,7 @@ fn ethers_tx_to_bytes<T: EthSpec>(
let s = transaction.s; let s = transaction.s;
let signature = EcdsaSignature { y_parity, r, s }; let signature = EcdsaSignature { y_parity, r, s };
// The `BLOB_TX_TYPE` should prepend the SSZ encoded `SignedBlobTransaction`.
let mut signed_tx = SignedBlobTransaction { message, signature }.as_ssz_bytes(); let mut signed_tx = SignedBlobTransaction { message, signature }.as_ssz_bytes();
signed_tx.insert(0, BLOB_TX_TYPE); signed_tx.insert(0, BLOB_TX_TYPE);
signed_tx signed_tx