diff --git a/CHANGELOG.md b/CHANGELOG.md index 8340fc71d31..c88dec1fa2f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - "gas-price-threshold-percent" - the threshold percent for determining if the gas price will be increase or decreased And the following CLI flags are serving a new purpose - "min-gas-price" - the minimum gas price that the gas price algorithm will return + +### Fixed + +#### Breaking +- [2045](https://github.com/FuelLabs/fuel-core/pull/2045): Include withdrawal message only if transaction is executed successfully. - [2041](https://github.com/FuelLabs/fuel-core/pull/2041): Add code for startup of the gas price algorithm updater so the gas price db on startup is always in sync with the on chain db diff --git a/crates/fuel-core/src/executor.rs b/crates/fuel-core/src/executor.rs index 151b6131d41..f493c5f01fb 100644 --- a/crates/fuel-core/src/executor.rs +++ b/crates/fuel-core/src/executor.rs @@ -54,7 +54,10 @@ mod tests { RegId, }, fuel_crypto::SecretKey, - fuel_merkle::sparse, + fuel_merkle::{ + common::empty_sum_sha256, + sparse, + }, fuel_tx::{ consensus_parameters::gas::GasCostsValuesV1, field::{ @@ -2528,6 +2531,109 @@ mod tests { )); } + #[test] + fn withdrawal_message_included_in_header_for_successfully_executed_transaction() { + // Given + let amount_from_random_input = 1000; + let smo_tx = TransactionBuilder::script( + vec![ + // The amount to send in coins. + op::movi(0x13, amount_from_random_input), + // Send the message output. + op::smo(0x0, 0x0, 0x0, 0x13), + op::ret(RegId::ONE), + ] + .into_iter() + .collect(), + vec![], + ) + .add_random_fee_input() + .script_gas_limit(1000000) + .finalize_as_transaction(); + + let block = PartialFuelBlock { + header: Default::default(), + transactions: vec![smo_tx], + }; + + // When + let ExecutionResult { block, .. } = + create_executor(Default::default(), Default::default()) + .produce_and_commit(block) + .expect("block execution failed unexpectedly"); + let result = create_executor(Default::default(), Default::default()) + .validate_and_commit(&block) + .expect("block validation failed unexpectedly"); + + // Then + let Some(Receipt::MessageOut { + sender, + recipient, + amount, + nonce, + data, + .. + }) = result.tx_status[0].result.receipts().first().cloned() + else { + panic!("Expected a MessageOut receipt"); + }; + + // Reconstruct merkle message outbox merkle root and see that it matches + let mut mt = fuel_core_types::fuel_merkle::binary::in_memory::MerkleTree::new(); + mt.push( + &Message::V1(MessageV1 { + sender, + recipient, + nonce, + amount, + data: data.unwrap_or_default(), + da_height: 1u64.into(), + }) + .message_id() + .to_bytes(), + ); + assert_eq!(block.header().message_outbox_root.as_ref(), mt.root()); + } + + #[test] + fn withdrawal_message_not_included_in_header_for_failed_transaction() { + // Given + let amount_from_random_input = 1000; + let smo_tx = TransactionBuilder::script( + vec![ + // The amount to send in coins. + op::movi(0x13, amount_from_random_input), + // Send the message output. + op::smo(0x0, 0x0, 0x0, 0x13), + op::rvrt(0x0), + ] + .into_iter() + .collect(), + vec![], + ) + .add_random_fee_input() + .script_gas_limit(1000000) + .finalize_as_transaction(); + + let block = PartialFuelBlock { + header: Default::default(), + transactions: vec![smo_tx], + }; + + // When + let ExecutionResult { block, .. } = + create_executor(Default::default(), Default::default()) + .produce_and_commit(block) + .expect("block execution failed unexpectedly"); + create_executor(Default::default(), Default::default()) + .validate_and_commit(&block) + .expect("block validation failed unexpectedly"); + + // Then + let empty_root = empty_sum_sha256(); + assert_eq!(block.header().message_outbox_root.as_ref(), empty_root) + } + #[test] fn get_block_height_returns_current_executing_block() { let mut rng = StdRng::seed_from_u64(1234); diff --git a/crates/services/executor/src/executor.rs b/crates/services/executor/src/executor.rs index 4993ecbd30c..1f9b5f43076 100644 --- a/crates/services/executor/src/executor.rs +++ b/crates/services/executor/src/executor.rs @@ -1365,9 +1365,13 @@ where .used_gas .checked_add(used_gas) .ok_or(ExecutorError::GasOverflow)?; - execution_data - .message_ids - .extend(receipts.iter().filter_map(|r| r.message_id())); + + if !reverted { + execution_data + .message_ids + .extend(receipts.iter().filter_map(|r| r.message_id())); + } + let status = if reverted { TransactionExecutionResult::Failed { result: Some(state),