Skip to content

Commit 0c6ad23

Browse files
committed
added v3_transactions_api_endpoint
1 parent 8a8192d commit 0c6ad23

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

testnet/stacks-node/src/tests/nakamoto_integrations.rs

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11402,3 +11402,158 @@ fn rbf_on_config_change() {
1140211402

1140311403
run_loop_thread.join().unwrap();
1140411404
}
11405+
11406+
/// Test `/v3/transactions/txid` API endpoint
11407+
///
11408+
/// This endpoint returns a JSON with index_block_hash,
11409+
/// the transaction body as hex and the transaction result.
11410+
#[test]
11411+
#[ignore]
11412+
fn v3_transactions_api_endpoint() {
11413+
if env::var("BITCOIND_TEST") != Ok("1".into()) {
11414+
return;
11415+
}
11416+
11417+
let (mut conf, _miner_account) = naka_neon_integration_conf(None);
11418+
conf.node.txindex = true;
11419+
11420+
let password = "12345".to_string();
11421+
conf.connection_options.auth_token = Some(password.clone());
11422+
conf.miner.wait_on_interim_blocks = Duration::from_secs(1);
11423+
let stacker_sk = setup_stacker(&mut conf);
11424+
let signer_sk = Secp256k1PrivateKey::random();
11425+
let signer_addr = tests::to_addr(&signer_sk);
11426+
let sender_sk = Secp256k1PrivateKey::random();
11427+
// setup sender + recipient for some test stx transfers
11428+
// these are necessary for the interim blocks to get mined at all
11429+
let sender_addr = tests::to_addr(&sender_sk);
11430+
let send_amt = 100;
11431+
let send_fee = 180;
11432+
conf.add_initial_balance(
11433+
PrincipalData::from(sender_addr).to_string(),
11434+
send_amt + send_fee,
11435+
);
11436+
conf.add_initial_balance(PrincipalData::from(signer_addr).to_string(), 100000);
11437+
11438+
// only subscribe to the block proposal events
11439+
test_observer::spawn();
11440+
test_observer::register(&mut conf, &[EventKeyType::MinedBlocks]);
11441+
11442+
let mut btcd_controller = BitcoinCoreController::new(conf.clone());
11443+
btcd_controller
11444+
.start_bitcoind()
11445+
.expect("Failed starting bitcoind");
11446+
let mut btc_regtest_controller = BitcoinRegtestController::new(conf.clone(), None);
11447+
btc_regtest_controller.bootstrap_chain(201);
11448+
11449+
let mut run_loop = boot_nakamoto::BootRunLoop::new(conf.clone()).unwrap();
11450+
let run_loop_stopper = run_loop.get_termination_switch();
11451+
let counters = run_loop.counters();
11452+
let Counters {
11453+
blocks_processed,
11454+
naka_submitted_commits: commits_submitted,
11455+
..
11456+
} = run_loop.counters();
11457+
11458+
let coord_channel = run_loop.coordinator_channels();
11459+
11460+
let run_loop_thread = thread::spawn(move || run_loop.start(None, 0));
11461+
let mut signers = TestSigners::new(vec![signer_sk]);
11462+
wait_for_runloop(&blocks_processed);
11463+
boot_to_epoch_3(
11464+
&conf,
11465+
&blocks_processed,
11466+
&[stacker_sk],
11467+
&[signer_sk],
11468+
&mut Some(&mut signers),
11469+
&mut btc_regtest_controller,
11470+
);
11471+
11472+
info!("------------------------- Reached Epoch 3.0 -------------------------");
11473+
11474+
blind_signer(&conf, &signers, &counters);
11475+
11476+
wait_for_first_naka_block_commit(60, &commits_submitted);
11477+
11478+
// Mine 1 nakamoto tenure
11479+
next_block_and_mine_commit(&mut btc_regtest_controller, 60, &conf, &counters).unwrap();
11480+
11481+
let burnchain = conf.get_burnchain();
11482+
let _sortdb = burnchain.open_sortition_db(true).unwrap();
11483+
let (_chainstate, _) = StacksChainState::open(
11484+
conf.is_mainnet(),
11485+
conf.burnchain.chain_id,
11486+
&conf.get_chainstate_path_str(),
11487+
None,
11488+
)
11489+
.unwrap();
11490+
11491+
info!("------------------------- Setup finished, run test -------------------------");
11492+
11493+
let http_origin = format!("http://{}", &conf.node.rpc_bind);
11494+
11495+
let get_v3_transactions = |txid: Txid| {
11496+
let url = &format!("{http_origin}/v3/transactions/{txid}");
11497+
info!("Send request: GET {url}");
11498+
reqwest::blocking::get(url)
11499+
.unwrap_or_else(|e| panic!("GET request failed: {e}"))
11500+
.json::<serde_json::Value>()
11501+
.unwrap()
11502+
};
11503+
11504+
let get_transaction_from_block = |index_block_hash: String, txid: String| {
11505+
for block_json in test_observer::get_blocks() {
11506+
if block_json["index_block_hash"].as_str().unwrap() == format!("0x{}", index_block_hash)
11507+
{
11508+
for transaction_json in block_json["transactions"].as_array().unwrap() {
11509+
if transaction_json["txid"].as_str().unwrap() == format!("0x{}", txid) {
11510+
return Some(transaction_json["raw_tx"].as_str().unwrap().to_string());
11511+
}
11512+
}
11513+
}
11514+
}
11515+
None
11516+
};
11517+
11518+
let block_events = test_observer::get_mined_nakamoto_blocks();
11519+
11520+
let last_block_event = block_events.last().unwrap();
11521+
11522+
let first_transaction = match last_block_event.tx_events.first().unwrap() {
11523+
TransactionEvent::Success(first_transaction) => Some(first_transaction.txid),
11524+
_ => None,
11525+
}
11526+
.unwrap();
11527+
11528+
let response_json = get_v3_transactions(first_transaction);
11529+
11530+
assert_eq!(
11531+
response_json
11532+
.get("index_block_hash")
11533+
.unwrap()
11534+
.as_str()
11535+
.unwrap(),
11536+
last_block_event.block_id
11537+
);
11538+
11539+
let raw_tx = get_transaction_from_block(
11540+
last_block_event.block_id.clone(),
11541+
first_transaction.to_hex(),
11542+
)
11543+
.unwrap();
11544+
11545+
assert_eq!(
11546+
format!("0x{}", response_json.get("tx").unwrap().as_str().unwrap()),
11547+
raw_tx
11548+
);
11549+
11550+
info!("------------------------- Test finished, clean up -------------------------");
11551+
11552+
coord_channel
11553+
.lock()
11554+
.expect("Mutex poisoned")
11555+
.stop_chains_coordinator();
11556+
run_loop_stopper.store(false, Ordering::SeqCst);
11557+
11558+
run_loop_thread.join().unwrap();
11559+
}

0 commit comments

Comments
 (0)