|
16 | 16 |
|
17 | 17 | use std::net::{IpAddr, Ipv4Addr, SocketAddr}; |
18 | 18 |
|
| 19 | +use stacks_common::consts::CHAIN_ID_TESTNET; |
19 | 20 | use stacks_common::types::chainstate::StacksBlockId; |
20 | 21 |
|
21 | | -use crate::chainstate::stacks::Error as ChainError; |
| 22 | +use crate::chainstate::stacks::{Error as ChainError, StacksTransaction}; |
| 23 | +use crate::core::test_util::make_contract_publish; |
22 | 24 | use crate::net::api::blockreplay; |
23 | 25 | use crate::net::api::tests::TestRPC; |
24 | 26 | use crate::net::connection::ConnectionOptions; |
25 | 27 | use crate::net::httpcore::{StacksHttp, StacksHttpRequest}; |
26 | 28 | use crate::net::test::TestEventObserver; |
27 | 29 | use crate::net::ProtocolFamily; |
| 30 | +use crate::stacks_common::codec::StacksMessageCodec; |
28 | 31 |
|
29 | 32 | #[test] |
30 | 33 | fn test_try_parse_request() { |
@@ -179,3 +182,91 @@ fn test_try_make_response() { |
179 | 182 | let (preamble, body) = response.destruct(); |
180 | 183 | assert_eq!(preamble.status_code, 401); |
181 | 184 | } |
| 185 | + |
| 186 | +#[test] |
| 187 | +fn test_try_make_response_with_unsuccessful_transaction() { |
| 188 | + let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 33333); |
| 189 | + |
| 190 | + let test_observer = TestEventObserver::new(); |
| 191 | + let rpc_test = |
| 192 | + TestRPC::setup_nakamoto_with_boot_plan(function_name!(), &test_observer, |boot_plan| { |
| 193 | + let mut tip_transactions: Vec<StacksTransaction> = vec![]; |
| 194 | + |
| 195 | + let miner_privk = boot_plan.private_key.clone(); |
| 196 | + |
| 197 | + let contract_code = "(broken)"; |
| 198 | + |
| 199 | + let deploy_tx_bytes = make_contract_publish( |
| 200 | + &miner_privk, |
| 201 | + 100, |
| 202 | + 1000, |
| 203 | + CHAIN_ID_TESTNET, |
| 204 | + &"err-contract", |
| 205 | + &contract_code, |
| 206 | + ); |
| 207 | + let deploy_tx = |
| 208 | + StacksTransaction::consensus_deserialize(&mut deploy_tx_bytes.as_slice()).unwrap(); |
| 209 | + |
| 210 | + tip_transactions.push(deploy_tx); |
| 211 | + boot_plan |
| 212 | + .with_tip_transactions(tip_transactions) |
| 213 | + .with_ignore_transaction_errors(true) |
| 214 | + }); |
| 215 | + |
| 216 | + let tip_block = test_observer.get_blocks().last().unwrap().clone(); |
| 217 | + |
| 218 | + let nakamoto_consensus_hash = rpc_test.consensus_hash.clone(); |
| 219 | + |
| 220 | + let mut requests = vec![]; |
| 221 | + |
| 222 | + let mut request = |
| 223 | + StacksHttpRequest::new_block_replay(addr.clone().into(), &rpc_test.canonical_tip); |
| 224 | + // add the authorization header |
| 225 | + request.add_header("authorization".into(), "password".into()); |
| 226 | + requests.push(request); |
| 227 | + |
| 228 | + let mut responses = rpc_test.run(requests); |
| 229 | + |
| 230 | + // got the Nakamoto tip |
| 231 | + let response = responses.remove(0); |
| 232 | + |
| 233 | + debug!( |
| 234 | + "Response:\n{}\n", |
| 235 | + std::str::from_utf8(&response.try_serialize().unwrap()).unwrap() |
| 236 | + ); |
| 237 | + |
| 238 | + let resp = response.decode_replayed_block().unwrap(); |
| 239 | + |
| 240 | + assert_eq!(resp.consensus_hash, nakamoto_consensus_hash); |
| 241 | + assert_eq!(resp.consensus_hash, tip_block.metadata.consensus_hash); |
| 242 | + |
| 243 | + assert_eq!(resp.block_hash, tip_block.block.block_hash); |
| 244 | + assert_eq!(resp.block_id, tip_block.metadata.index_block_hash()); |
| 245 | + assert_eq!(resp.parent_block_id, tip_block.parent); |
| 246 | + |
| 247 | + assert_eq!(resp.block_height, tip_block.metadata.stacks_block_height); |
| 248 | + |
| 249 | + assert!(resp.valid_merkle_root); |
| 250 | + |
| 251 | + assert_eq!(resp.transactions.len(), tip_block.receipts.len()); |
| 252 | + |
| 253 | + for tx_index in 0..resp.transactions.len() { |
| 254 | + assert_eq!( |
| 255 | + resp.transactions[tx_index].txid, |
| 256 | + tip_block.receipts[tx_index].transaction.txid() |
| 257 | + ); |
| 258 | + assert_eq!( |
| 259 | + resp.transactions[tx_index].events.len(), |
| 260 | + tip_block.receipts[tx_index].events.len() |
| 261 | + ); |
| 262 | + assert_eq!( |
| 263 | + resp.transactions[tx_index].result, |
| 264 | + tip_block.receipts[tx_index].result |
| 265 | + ); |
| 266 | + } |
| 267 | + |
| 268 | + assert_eq!( |
| 269 | + resp.transactions.last().unwrap().vm_error.clone().unwrap(), |
| 270 | + ":0:0: use of unresolved function 'broken'" |
| 271 | + ); |
| 272 | +} |
0 commit comments