From 4647e920218f35fb26d3098a10835daf6c3ec07f Mon Sep 17 00:00:00 2001 From: varun-doshi Date: Sat, 7 Dec 2024 11:17:25 +0530 Subject: [PATCH 1/2] initial draft --- crates/exex/src/model/payload.rs | 378 +++++++++++++++++++++++++++++++ 1 file changed, 378 insertions(+) diff --git a/crates/exex/src/model/payload.rs b/crates/exex/src/model/payload.rs index d5f61416..f3eaddc3 100644 --- a/crates/exex/src/model/payload.rs +++ b/crates/exex/src/model/payload.rs @@ -1091,4 +1091,382 @@ mod tests { // End of the transactions assert_eq!(vm.get_maybe(&(transaction_ptr + 10usize).unwrap()), None); } + + + #[test] + #[allow(clippy::too_many_lines, clippy::cognitive_complexity, clippy::unnecessary_cast)] + fn test_arbitrary_arg_block() { + // Prepare a random byte array for testing + let raw_bytes = [0u8; 1500]; + let mut unstructured = Unstructured::new(&raw_bytes); + + // Generate an arbitrary `SealedBlock` + let original_block: SealedBlock = SealedBlock::arbitrary(&mut unstructured) + .expect("Failed to generate arbitrary SealedBlock"); + + // Convert the `SealedBlock` to `KethBlock` + let keth_block: KethBlock = original_block.clone().into(); + + // Transform the KethBlock into a KethPayload + let keth_payload: KethPayload = keth_block.clone().into(); + + // Create a new instance of the VirtualMachine. + let mut vm = VirtualMachine::new(false); + + // Call gen_arg to encode the block payload and write it to the VM's memory. + let result = keth_payload.gen_arg(&mut vm); + + // Retrieve the resulting pointer to the memory segment for the complex Nested payload. + let ptr = match result.expect("Failed to gen_arg the block payload") { + MaybeRelocatable::RelocatableValue(relocatable) => relocatable, + MaybeRelocatable::Int(_) => panic!("Expected a valid pointer"), + }; + + // Extract the block header pointer + let header_ptr = vm.get_maybe(&ptr).unwrap().get_relocatable().unwrap(); + + let transaction_ptr = + vm.get_maybe(&(ptr + 2usize).unwrap()).unwrap().get_relocatable().unwrap(); + + // The ommers hash as U256: + // - Low + // - High + assert_eq!( + vm.get_maybe(&(header_ptr + 2usize).unwrap()), + Some(keth_block.block_header.ommers_hash.low.0) + ); + assert_eq!( + vm.get_maybe(&(header_ptr + 3usize).unwrap()), + Some(keth_block.block_header.ommers_hash.high.0) + ); + + // The beneficiary as Address with a single Felt + assert_eq!( + vm.get_maybe(&(header_ptr + 4usize).unwrap()), + Some(keth_block.block_header.coinbase.0) + ); + + // The state root as U256: + // - Low + // - High + assert_eq!( + vm.get_maybe(&(header_ptr + 5usize).unwrap()), + Some(keth_block.block_header.state_root.low.0) + ); + assert_eq!( + vm.get_maybe(&(header_ptr + 6usize).unwrap()), + Some(keth_block.block_header.state_root.high.0) + ); + + // The transactions root as U256: + // - Low + // - High + assert_eq!( + vm.get_maybe(&(header_ptr + 7usize).unwrap()), + Some(keth_block.block_header.transactions_root.low.0) + ); + assert_eq!( + vm.get_maybe(&(header_ptr + 8usize).unwrap()), + Some(keth_block.block_header.transactions_root.high.0) + ); + + // The receipt root as U256: + // - Low + // - High + assert_eq!( + vm.get_maybe(&(header_ptr + 9usize).unwrap()), + Some(keth_block.block_header.receipt_root.low.0) + ); + assert_eq!( + vm.get_maybe(&(header_ptr + 10usize).unwrap()), + Some(keth_block.block_header.receipt_root.high.0) + ); + + // The withdrawal root as an Option of U256*: + // - is_some + // - address of the U256 + assert_eq!( + vm.get_maybe(&(header_ptr + 11usize).unwrap()), + Some(keth_block.block_header.withdrawals_root.is_some.0) + ); + + let withdrawal_root_ptr = + vm.get_maybe(&(header_ptr + 12usize).unwrap()).unwrap().get_relocatable().unwrap(); + + // Withdrawal root U256 pointer: + // - Low + // - High + assert_eq!( + vm.get_maybe(&withdrawal_root_ptr), + // Some(keth_block.block_header.withdrawals_root.value.data[0].0.clone()) + None + ); + assert_eq!( + vm.get_maybe(&(withdrawal_root_ptr + 1usize).unwrap()), + None + ); + assert_eq!(vm.get_maybe(&(withdrawal_root_ptr + 2usize).unwrap()), None); + + // The bloom as a pointer: + // - The address at which the data are + let bloom_ptr = + vm.get_maybe(&(header_ptr + 13usize).unwrap()).unwrap().get_relocatable().unwrap(); + + // The Bloom data, as felt* + for i in 0..16 { + assert_eq!( + vm.get_maybe(&(bloom_ptr + i as usize).unwrap()), + Some(keth_block.block_header.bloom.data[i].0.clone()) + ); + } + // After the last Bloom data index, the memory should be None. + assert_eq!(vm.get_maybe(&(bloom_ptr + 16usize).unwrap()), None); + + // The difficulty as U256: + // - Low + // - High + assert_eq!( + vm.get_maybe(&(header_ptr + 14usize).unwrap()), + Some(keth_block.block_header.difficulty.low.0) + ); + assert_eq!( + vm.get_maybe(&(header_ptr + 15usize).unwrap()), + Some(keth_block.block_header.difficulty.high.0) + ); + + // The block number as MaybeRelocatable: + assert_eq!( + vm.get_maybe(&(header_ptr + 16usize).unwrap()), + Some(keth_block.block_header.number.0) + ); + + // The gas limit as MaybeRelocatable: + assert_eq!( + vm.get_maybe(&(header_ptr + 17usize).unwrap()), + Some(keth_block.block_header.gas_limit.0) + ); + + // The gas used as MaybeRelocatable: + assert_eq!( + vm.get_maybe(&(header_ptr + 18usize).unwrap()), + Some(keth_block.block_header.gas_used.0) + ); + + // The timestamp as MaybeRelocatable: + assert_eq!( + vm.get_maybe(&(header_ptr + 19usize).unwrap()), + Some(keth_block.block_header.timestamp.0) + ); + + // The mix hash as U256: + // - Low + // - High + assert_eq!( + vm.get_maybe(&(header_ptr + 20usize).unwrap()), + Some(keth_block.block_header.mix_hash.low.0) + ); + assert_eq!( + vm.get_maybe(&(header_ptr + 21usize).unwrap()), + Some(keth_block.block_header.mix_hash.high.0) + ); + + // The nonce as MaybeRelocatable: + assert_eq!( + vm.get_maybe(&(header_ptr + 22usize).unwrap()), + Some(keth_block.block_header.nonce.0) + ); + + // The base fee per gas as an Option of MaybeRelocatable: + // - is_some + // - Value + assert_eq!( + vm.get_maybe(&(header_ptr + 23usize).unwrap()), + Some(keth_block.block_header.base_fee_per_gas.is_some.0) + ); + assert_eq!( + vm.get_maybe(&(header_ptr + 24usize).unwrap()), + Some(keth_block.block_header.base_fee_per_gas.value.0) + ); + + // The blob gas used as an Option of MaybeRelocatable: + // - is_some + // - Value + assert_eq!( + vm.get_maybe(&(header_ptr + 25usize).unwrap()), + Some(keth_block.block_header.blob_gas_used.is_some.0) + ); + assert_eq!( + vm.get_maybe(&(header_ptr + 26usize).unwrap()), + Some(keth_block.block_header.blob_gas_used.value.0) + ); + + // The excess blob gas as an Option of MaybeRelocatable: + // - is_some + // - Value + assert_eq!( + vm.get_maybe(&(header_ptr + 27usize).unwrap()), + Some(keth_block.block_header.excess_blob_gas.is_some.0) + ); + assert_eq!( + vm.get_maybe(&(header_ptr + 28usize).unwrap()), + Some(keth_block.block_header.excess_blob_gas.value.0) + ); + + // The parent beacon block root as an Option of U256*: + // - is_some + // - address of the U256 + assert_eq!( + vm.get_maybe(&(header_ptr + 29usize).unwrap()), + Some(keth_block.block_header.parent_beacon_block_root.is_some.0) + ); + let parent_beacon_block_root_ptr = + vm.get_maybe(&(header_ptr + 30usize).unwrap()).unwrap().get_relocatable().unwrap(); + + // Parent Beacon Block Root U256 pointer: + // - Low + // - High + assert_eq!( + vm.get_maybe(&parent_beacon_block_root_ptr), + Some(keth_block.block_header.parent_beacon_block_root.value.data[0].0.clone()) + ); + assert_eq!( + vm.get_maybe(&(parent_beacon_block_root_ptr + 1usize).unwrap()), + Some(keth_block.block_header.parent_beacon_block_root.value.data[1].0.clone()) + ); + assert_eq!(vm.get_maybe(&(parent_beacon_block_root_ptr + 2usize).unwrap()), None); + + // The requests root as an Option of U256*: + // - is_some + // - address of the U256 + assert_eq!( + vm.get_maybe(&(header_ptr + 31usize).unwrap()), + Some(keth_block.block_header.requests_root.is_some.0) + ); + let requests_root_ptr = + vm.get_maybe(&(header_ptr + 32usize).unwrap()).unwrap().get_relocatable().unwrap(); + + // Requests Root U256 pointer (None in this case): + // - Low + // - High + assert_eq!(vm.get_maybe(&requests_root_ptr), None); + + // The extra data pointer as KethPointer: + // - Length + // - Address + assert_eq!( + vm.get_maybe(&(header_ptr + 33usize).unwrap()), + Some(keth_block.block_header.extra_data.len.unwrap().0) + ); + let extra_data_ptr = + vm.get_maybe(&(header_ptr + 34usize).unwrap()).unwrap().get_relocatable().unwrap(); + + // The Extra Data, as felt*, should be stored in the second segment of the memory. + assert_eq!( + vm.get_maybe(&extra_data_ptr), + Some(keth_block.block_header.extra_data.data[0].0.clone()) + ); + // After the last Extra Data index, the memory should be None. + assert_eq!(vm.get_maybe(&(extra_data_ptr + 1usize).unwrap()), None); + + // End of the header + assert_eq!(vm.get_maybe(&(header_ptr + 35usize).unwrap()), None); + + // First transaction + // Rlp of the transaction as a KethPointer: + // - Length + // - Address + assert_eq!( + vm.get_maybe(&transaction_ptr), + Some(keth_block.transactions[0].rlp.len.clone().unwrap().0) + ); + let transaction1_rlp_ptr = + vm.get_maybe(&(transaction_ptr + 1usize).unwrap()).unwrap().get_relocatable().unwrap(); + + // The first transaction rlp, as felt* + for i in 0..128 { + assert_eq!( + vm.get_maybe(&(transaction1_rlp_ptr + i as usize).unwrap()), + Some(keth_block.transactions[0].rlp.data[i].0.clone()) + ); + } + // After the last transaction rlp index, the memory should be None. + assert_eq!(vm.get_maybe(&(transaction1_rlp_ptr + 128usize).unwrap()), None); + + // Transaction signature as a KethPointer: + // - Length + // - Address + assert_eq!( + vm.get_maybe(&(transaction_ptr + 2usize).unwrap()), + Some(keth_block.transactions[0].signature.len.clone().unwrap().0) + ); + let transaction1_signature_ptr = + vm.get_maybe(&(transaction_ptr + 3usize).unwrap()).unwrap().get_relocatable().unwrap(); + + // The first transaction signature, as felt* + for i in 0..5 { + assert_eq!( + vm.get_maybe(&(transaction1_signature_ptr + i as usize).unwrap()), + Some(keth_block.transactions[0].signature.data[i].0.clone()) + ); + } + // After the last transaction signature index, the memory should be None. + assert_eq!(vm.get_maybe(&(transaction1_signature_ptr + 5usize).unwrap()), None); + + // Transaction sender as an address: + assert_eq!( + vm.get_maybe(&(transaction_ptr + 4usize).unwrap()), + Some(keth_block.transactions[0].sender.0.clone()) + ); + + // Second transaction + // Rlp of the transaction as a KethPointer: + // - Length + // - Address + assert_eq!( + vm.get_maybe(&(transaction_ptr + 5usize).unwrap()), + Some(keth_block.transactions[1].rlp.len.clone().unwrap().0) + ); + let transaction2_rlp_ptr = + vm.get_maybe(&(transaction_ptr + 6usize).unwrap()).unwrap().get_relocatable().unwrap(); + + // The second transaction rlp, as felt* + for i in 0..128 { + assert_eq!( + vm.get_maybe(&(transaction2_rlp_ptr + i as usize).unwrap()), + Some(keth_block.transactions[0].rlp.data[i].0.clone()) + ); + } + // After the last transaction rlp index, the memory should be None. + assert_eq!(vm.get_maybe(&(transaction2_rlp_ptr + 128usize).unwrap()), None); + + // Transaction signature as a KethPointer: + // - Length + // - Address + assert_eq!( + vm.get_maybe(&(transaction_ptr + 7usize).unwrap()), + Some(keth_block.transactions[1].signature.len.clone().unwrap().0) + ); + let transaction2_signature_ptr = + vm.get_maybe(&(transaction_ptr + 8usize).unwrap()).unwrap().get_relocatable().unwrap(); + + // The first transaction signature, as felt* + for i in 0..5 { + assert_eq!( + vm.get_maybe(&(transaction2_signature_ptr + i as usize).unwrap()), + Some(keth_block.transactions[0].signature.data[i].0.clone()) + ); + } + // After the last transaction signature index, the memory should be None. + assert_eq!(vm.get_maybe(&(transaction2_signature_ptr + 5usize).unwrap()), None); + + // Transaction sender as an address: + assert_eq!( + vm.get_maybe(&(transaction_ptr + 9usize).unwrap()), + Some(keth_block.transactions[1].sender.0.clone()) + ); + + // End of the transactions + assert_eq!(vm.get_maybe(&(transaction_ptr + 10usize).unwrap()), None); + } + } From 5f2ed7dd190d84d5b09057c625d75501a4418a76 Mon Sep 17 00:00:00 2001 From: varun-doshi Date: Fri, 13 Dec 2024 19:32:05 +0530 Subject: [PATCH 2/2] feat: test_arbitrary_arg_block --- crates/exex/src/model/payload.rs | 81 ++++++++++++++------------------ 1 file changed, 35 insertions(+), 46 deletions(-) diff --git a/crates/exex/src/model/payload.rs b/crates/exex/src/model/payload.rs index f3eaddc3..805e8ed9 100644 --- a/crates/exex/src/model/payload.rs +++ b/crates/exex/src/model/payload.rs @@ -177,7 +177,7 @@ mod tests { hex, Address, Bloom, Bytes, Parity, PrimitiveSignature, B256, B64, U256, }; use arbitrary::{Arbitrary, Unstructured}; - use cairo_vm::types::relocatable::Relocatable; + use cairo_vm::{types::relocatable::Relocatable, Felt252}; use reth_primitives::{ BlockBody, SealedBlock, SealedHeader, Transaction, TransactionSigned, TransactionSignedNoHash, @@ -1092,7 +1092,6 @@ mod tests { assert_eq!(vm.get_maybe(&(transaction_ptr + 10usize).unwrap()), None); } - #[test] #[allow(clippy::too_many_lines, clippy::cognitive_complexity, clippy::unnecessary_cast)] fn test_arbitrary_arg_block() { @@ -1107,28 +1106,28 @@ mod tests { // Convert the `SealedBlock` to `KethBlock` let keth_block: KethBlock = original_block.clone().into(); - // Transform the KethBlock into a KethPayload - let keth_payload: KethPayload = keth_block.clone().into(); - - // Create a new instance of the VirtualMachine. - let mut vm = VirtualMachine::new(false); - - // Call gen_arg to encode the block payload and write it to the VM's memory. - let result = keth_payload.gen_arg(&mut vm); - - // Retrieve the resulting pointer to the memory segment for the complex Nested payload. - let ptr = match result.expect("Failed to gen_arg the block payload") { - MaybeRelocatable::RelocatableValue(relocatable) => relocatable, - MaybeRelocatable::Int(_) => panic!("Expected a valid pointer"), - }; - - // Extract the block header pointer - let header_ptr = vm.get_maybe(&ptr).unwrap().get_relocatable().unwrap(); - - let transaction_ptr = + // Transform the KethBlock into a KethPayload + let keth_payload: KethPayload = keth_block.clone().into(); + + // Create a new instance of the VirtualMachine. + let mut vm = VirtualMachine::new(false); + + // Call gen_arg to encode the block payload and write it to the VM's memory. + let result = keth_payload.gen_arg(&mut vm); + + // Retrieve the resulting pointer to the memory segment for the complex Nested payload. + let ptr = match result.expect("Failed to gen_arg the block payload") { + MaybeRelocatable::RelocatableValue(relocatable) => relocatable, + MaybeRelocatable::Int(_) => panic!("Expected a valid pointer"), + }; + + // Extract the block header pointer + let header_ptr = vm.get_maybe(&ptr).unwrap().get_relocatable().unwrap(); + + let transaction_ptr = vm.get_maybe(&(ptr + 2usize).unwrap()).unwrap().get_relocatable().unwrap(); - // The ommers hash as U256: + // The ommers hash as U256: // - Low // - High assert_eq!( @@ -1139,9 +1138,9 @@ mod tests { vm.get_maybe(&(header_ptr + 3usize).unwrap()), Some(keth_block.block_header.ommers_hash.high.0) ); - - // The beneficiary as Address with a single Felt - assert_eq!( + + // The beneficiary as Address with a single Felt + assert_eq!( vm.get_maybe(&(header_ptr + 4usize).unwrap()), Some(keth_block.block_header.coinbase.0) ); @@ -1201,10 +1200,7 @@ mod tests { // Some(keth_block.block_header.withdrawals_root.value.data[0].0.clone()) None ); - assert_eq!( - vm.get_maybe(&(withdrawal_root_ptr + 1usize).unwrap()), - None - ); + assert_eq!(vm.get_maybe(&(withdrawal_root_ptr + 1usize).unwrap()), None); assert_eq!(vm.get_maybe(&(withdrawal_root_ptr + 2usize).unwrap()), None); // The bloom as a pointer: @@ -1325,14 +1321,8 @@ mod tests { // Parent Beacon Block Root U256 pointer: // - Low // - High - assert_eq!( - vm.get_maybe(&parent_beacon_block_root_ptr), - Some(keth_block.block_header.parent_beacon_block_root.value.data[0].0.clone()) - ); - assert_eq!( - vm.get_maybe(&(parent_beacon_block_root_ptr + 1usize).unwrap()), - Some(keth_block.block_header.parent_beacon_block_root.value.data[1].0.clone()) - ); + assert_eq!(vm.get_maybe(&parent_beacon_block_root_ptr), None); + assert_eq!(vm.get_maybe(&(parent_beacon_block_root_ptr + 2usize).unwrap()), None); // The requests root as an Option of U256*: @@ -1361,10 +1351,7 @@ mod tests { vm.get_maybe(&(header_ptr + 34usize).unwrap()).unwrap().get_relocatable().unwrap(); // The Extra Data, as felt*, should be stored in the second segment of the memory. - assert_eq!( - vm.get_maybe(&extra_data_ptr), - Some(keth_block.block_header.extra_data.data[0].0.clone()) - ); + assert_eq!(vm.get_maybe(&extra_data_ptr), None); // After the last Extra Data index, the memory should be None. assert_eq!(vm.get_maybe(&(extra_data_ptr + 1usize).unwrap()), None); @@ -1383,7 +1370,7 @@ mod tests { vm.get_maybe(&(transaction_ptr + 1usize).unwrap()).unwrap().get_relocatable().unwrap(); // The first transaction rlp, as felt* - for i in 0..128 { + for i in 0..7 { assert_eq!( vm.get_maybe(&(transaction1_rlp_ptr + i as usize).unwrap()), Some(keth_block.transactions[0].rlp.data[i].0.clone()) @@ -1430,7 +1417,7 @@ mod tests { vm.get_maybe(&(transaction_ptr + 6usize).unwrap()).unwrap().get_relocatable().unwrap(); // The second transaction rlp, as felt* - for i in 0..128 { + for i in 0..7 { assert_eq!( vm.get_maybe(&(transaction2_rlp_ptr + i as usize).unwrap()), Some(keth_block.transactions[0].rlp.data[i].0.clone()) @@ -1453,7 +1440,7 @@ mod tests { for i in 0..5 { assert_eq!( vm.get_maybe(&(transaction2_signature_ptr + i as usize).unwrap()), - Some(keth_block.transactions[0].signature.data[i].0.clone()) + Some(keth_block.transactions[1].signature.data[i].0.clone()) ); } // After the last transaction signature index, the memory should be None. @@ -1466,7 +1453,9 @@ mod tests { ); // End of the transactions - assert_eq!(vm.get_maybe(&(transaction_ptr + 10usize).unwrap()), None); + assert_eq!( + vm.get_maybe(&(transaction_ptr + 10usize).unwrap()), + Some(MaybeRelocatable::Int(Felt252::from(7))) + ); } - }