diff --git a/stackslib/src/chainstate/stacks/transaction.rs b/stackslib/src/chainstate/stacks/transaction.rs index c45b212b68..b9eb3b5ac3 100644 --- a/stackslib/src/chainstate/stacks/transaction.rs +++ b/stackslib/src/chainstate/stacks/transaction.rs @@ -34,6 +34,7 @@ use crate::chainstate::stacks::{TransactionPayloadID, *}; use crate::codec::Error as CodecError; use crate::core::*; use crate::net::Error as net_error; +use crate::util_lib::boot::boot_code_addr; impl StacksMessageCodec for TransactionContractCall { fn consensus_serialize(&self, fd: &mut W) -> Result<(), codec_error> { @@ -1031,6 +1032,16 @@ impl StacksTransaction { _ => false, } } + + /// Is this a phantom transaction? + pub fn is_phantom(&self) -> bool { + let boot_address = boot_code_addr(self.is_mainnet()).into(); + if let TransactionPayload::TokenTransfer(address, amount, _) = &self.payload { + *address == boot_address && *amount == 0 + } else { + false + } + } } impl StacksTransactionSigner { diff --git a/testnet/stacks-node/src/tests/neon_integrations.rs b/testnet/stacks-node/src/tests/neon_integrations.rs index fc363d3db8..fbe7421ab2 100644 --- a/testnet/stacks-node/src/tests/neon_integrations.rs +++ b/testnet/stacks-node/src/tests/neon_integrations.rs @@ -578,7 +578,7 @@ pub mod test_observer { PROPOSAL_RESPONSES.lock().unwrap().clear(); } - /// Parse the StacksTransactions from a block (does not include burn ops) + /// Parse the StacksTransactions from a block (does not include burn ops or phantom txs) /// panics on any failures to parse pub fn parse_transactions(block: &serde_json::Value) -> Vec { block @@ -588,15 +588,20 @@ pub mod test_observer { .unwrap() .iter() .filter_map(|tx_json| { + // Filter out burn ops if let Some(burnchain_op_val) = tx_json.get("burnchain_op") { if !burnchain_op_val.is_null() { return None; } } + // Filter out phantom txs let tx_hex = tx_json.get("raw_tx").unwrap().as_str().unwrap(); let tx_bytes = hex_bytes(&tx_hex[2..]).unwrap(); let tx = StacksTransaction::consensus_deserialize(&mut tx_bytes.as_slice()).unwrap(); + if tx.is_phantom() { + return None; + } Some(tx) }) .collect()