check byte length when converting to uint256 and hash256 from bytes. Add comments
This commit is contained in:
parent
8661477675
commit
dd40adc5c0
@ -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,8 +2126,14 @@ 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(
|
|
||||||
ð2_serde_utils::hex::decode(
|
// ******************** BlobTransaction `other` fields ********************
|
||||||
|
//
|
||||||
|
// Here we use the `other` field in the `ethers-rs` `Transaction` type because
|
||||||
|
// `ethers-rs` does not yet support SSZ and therefore the blobs transaction type.
|
||||||
|
|
||||||
|
// maxFeePerDataGas
|
||||||
|
let data_gas_bytes = eth2_serde_utils::hex::decode(
|
||||||
transaction
|
transaction
|
||||||
.other
|
.other
|
||||||
.get("maxFeePerDataGas")
|
.get("maxFeePerDataGas")
|
||||||
@ -2111,8 +2141,14 @@ fn ethers_tx_to_bytes<T: EthSpec>(
|
|||||||
.as_str()
|
.as_str()
|
||||||
.ok_or(BlobTxConversionError::MaxFeePerDataGasMissing)?,
|
.ok_or(BlobTxConversionError::MaxFeePerDataGasMissing)?,
|
||||||
)
|
)
|
||||||
.map_err(BlobTxConversionError::FromHexError)?,
|
.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(
|
||||||
ð2_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
|
||||||
|
Loading…
Reference in New Issue
Block a user