Skip to content

Commit 0bd617b

Browse files
authored
Merge branch 'develop' into feat/pox-4-tests-nakamoto
2 parents 3c5c45a + 1855e19 commit 0bd617b

File tree

3 files changed

+191
-8
lines changed

3 files changed

+191
-8
lines changed

testnet/stacks-node/src/burnchains/bitcoin_regtest_controller.rs

Lines changed: 191 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,22 +1373,44 @@ impl BitcoinRegtestController {
13731373
previous_fees: Option<LeaderBlockCommitFees>,
13741374
previous_txids: &Vec<Txid>,
13751375
) -> Option<Transaction> {
1376-
let mut estimated_fees = match previous_fees {
1376+
let _ = self.sortdb_mut();
1377+
let burn_chain_tip = self.burnchain_db.as_ref()?.get_canonical_chain_tip().ok()?;
1378+
let estimated_fees = match previous_fees {
13771379
Some(fees) => fees.fees_from_previous_tx(&payload, &self.config),
13781380
None => LeaderBlockCommitFees::estimated_fees_from_payload(&payload, &self.config),
13791381
};
13801382

1381-
let _ = self.sortdb_mut();
1382-
let burn_chain_tip = self.burnchain_db.as_ref()?.get_canonical_chain_tip().ok()?;
1383+
self.send_block_commit_operation_at_burnchain_height(
1384+
epoch_id,
1385+
payload,
1386+
signer,
1387+
utxos_to_include,
1388+
utxos_to_exclude,
1389+
estimated_fees,
1390+
previous_txids,
1391+
burn_chain_tip.block_height,
1392+
)
1393+
}
13831394

1395+
fn send_block_commit_operation_at_burnchain_height(
1396+
&mut self,
1397+
epoch_id: StacksEpochId,
1398+
payload: LeaderBlockCommitOp,
1399+
signer: &mut BurnchainOpSigner,
1400+
utxos_to_include: Option<UTXOSet>,
1401+
utxos_to_exclude: Option<UTXOSet>,
1402+
mut estimated_fees: LeaderBlockCommitFees,
1403+
previous_txids: &Vec<Txid>,
1404+
burnchain_block_height: u64,
1405+
) -> Option<Transaction> {
13841406
let public_key = signer.get_public_key();
13851407
let (mut tx, mut utxos) = self.prepare_tx(
13861408
epoch_id,
13871409
&public_key,
13881410
estimated_fees.estimated_amount_required(),
13891411
utxos_to_include,
13901412
utxos_to_exclude,
1391-
burn_chain_tip.block_height,
1413+
burnchain_block_height,
13921414
)?;
13931415

13941416
// Serialize the payload
@@ -1817,7 +1839,7 @@ impl BitcoinRegtestController {
18171839
debug!("Not enough change to clear dust limit. Not adding change address.");
18181840
}
18191841

1820-
for (i, utxo) in utxos_set.utxos.iter().enumerate() {
1842+
for (_i, utxo) in utxos_set.utxos.iter().enumerate() {
18211843
let input = TxIn {
18221844
previous_output: OutPoint {
18231845
txid: utxo.txid,
@@ -1828,7 +1850,8 @@ impl BitcoinRegtestController {
18281850
witness: vec![],
18291851
};
18301852
tx.input.push(input);
1831-
1853+
}
1854+
for (i, utxo) in utxos_set.utxos.iter().enumerate() {
18321855
let script_pub_key = utxo.script_pub_key.clone();
18331856
let sig_hash_all = 0x01;
18341857

@@ -2805,6 +2828,12 @@ mod tests {
28052828
use std::fs::File;
28062829
use std::io::Write;
28072830

2831+
use stacks::burnchains::BurnchainSigner;
2832+
use stacks_common::deps_common::bitcoin::blockdata::script::Builder;
2833+
use stacks_common::types::chainstate::{BlockHeaderHash, StacksAddress, VRFSeed};
2834+
use stacks_common::util::hash::to_hex;
2835+
use stacks_common::util::secp256k1::Secp256k1PrivateKey;
2836+
28082837
use super::*;
28092838
use crate::config::DEFAULT_SATS_PER_VB;
28102839

@@ -2825,4 +2854,160 @@ mod tests {
28252854

28262855
assert_eq!(get_satoshis_per_byte(&config), 51);
28272856
}
2857+
2858+
/// Verify that we can build a valid Bitcoin transaction with multiple UTXOs.
2859+
/// Taken from production data.
2860+
/// Tests `serialize_tx()` and `send_block_commit_operation_at_burnchain_height()`
2861+
#[test]
2862+
fn test_multiple_inputs() {
2863+
let spend_utxos = vec![
2864+
UTXO {
2865+
txid: Sha256dHash::from_hex(
2866+
"d3eafb3aba3cec925473550ed2e4d00bcb0d00744bb3212e4a8e72878909daee",
2867+
)
2868+
.unwrap(),
2869+
vout: 3,
2870+
script_pub_key: Builder::from(
2871+
hex_bytes("76a9141dc27eba0247f8cc9575e7d45e50a0bc7e72427d88ac").unwrap(),
2872+
)
2873+
.into_script(),
2874+
amount: 42051,
2875+
confirmations: 1421,
2876+
},
2877+
UTXO {
2878+
txid: Sha256dHash::from_hex(
2879+
"01132f2d4a98cc715624e033214c8d841098a1ee15b30188ab89589a320b3b24",
2880+
)
2881+
.unwrap(),
2882+
vout: 0,
2883+
script_pub_key: Builder::from(
2884+
hex_bytes("76a9141dc27eba0247f8cc9575e7d45e50a0bc7e72427d88ac").unwrap(),
2885+
)
2886+
.into_script(),
2887+
amount: 326456,
2888+
confirmations: 1421,
2889+
},
2890+
];
2891+
2892+
// test serialize_tx()
2893+
let mut config = Config::default();
2894+
config.burnchain.magic_bytes = "T3".as_bytes().into();
2895+
2896+
let mut btc_controller = BitcoinRegtestController::new(config, None);
2897+
let mut utxo_set = UTXOSet {
2898+
bhh: BurnchainHeaderHash([0x01; 32]),
2899+
utxos: spend_utxos.clone(),
2900+
};
2901+
let mut transaction = Transaction {
2902+
input: vec![],
2903+
output: vec![
2904+
TxOut {
2905+
value: 0,
2906+
script_pubkey: Builder::from(hex_bytes("6a4c5054335be88c3d30cb59a142f83de3b27f897a43bbb0f13316911bb98a3229973dae32afd5b9f21bc1f40f24e2c101ecd13c55b8619e5e03dad81de2c62a1cc1d8c1b375000008a300010000059800015a").unwrap()).into_script(),
2907+
},
2908+
TxOut {
2909+
value: 10000,
2910+
script_pubkey: Builder::from(hex_bytes("76a914000000000000000000000000000000000000000088ac").unwrap()).into_script(),
2911+
},
2912+
TxOut {
2913+
value: 10000,
2914+
script_pubkey: Builder::from(hex_bytes("76a914000000000000000000000000000000000000000088ac").unwrap()).into_script(),
2915+
},
2916+
],
2917+
version: 1,
2918+
lock_time: 0,
2919+
};
2920+
2921+
let mut signer = BurnchainOpSigner::new(
2922+
Secp256k1PrivateKey::from_hex(
2923+
"9e446f6b0c6a96cf2190e54bcd5a8569c3e386f091605499464389b8d4e0bfc201",
2924+
)
2925+
.unwrap(),
2926+
false,
2927+
);
2928+
assert!(btc_controller.serialize_tx(
2929+
StacksEpochId::Epoch25,
2930+
&mut transaction,
2931+
44950,
2932+
&mut utxo_set,
2933+
&mut signer,
2934+
true
2935+
));
2936+
assert_eq!(transaction.output[3].value, 323557);
2937+
2938+
// test send_block_commit_operation_at_burn_height()
2939+
let utxo_set = UTXOSet {
2940+
bhh: BurnchainHeaderHash([0x01; 32]),
2941+
utxos: spend_utxos.clone(),
2942+
};
2943+
2944+
let commit_op = LeaderBlockCommitOp {
2945+
block_header_hash: BlockHeaderHash::from_hex(
2946+
"e88c3d30cb59a142f83de3b27f897a43bbb0f13316911bb98a3229973dae32af",
2947+
)
2948+
.unwrap(),
2949+
new_seed: VRFSeed::from_hex(
2950+
"d5b9f21bc1f40f24e2c101ecd13c55b8619e5e03dad81de2c62a1cc1d8c1b375",
2951+
)
2952+
.unwrap(),
2953+
parent_block_ptr: 2211, // 0x000008a3
2954+
parent_vtxindex: 1, // 0x0001
2955+
key_block_ptr: 1432, // 0x00000598
2956+
key_vtxindex: 1, // 0x0001
2957+
memo: vec![11], // 0x5a >> 3
2958+
2959+
burn_fee: 0,
2960+
input: (Txid([0x00; 32]), 0),
2961+
burn_parent_modulus: 2, // 0x5a & 0b111
2962+
2963+
apparent_sender: BurnchainSigner("mgbpit8FvkVJ9kuXY8QSM5P7eibnhcEMBk".to_string()),
2964+
commit_outs: vec![
2965+
PoxAddress::Standard(StacksAddress::burn_address(false), None),
2966+
PoxAddress::Standard(StacksAddress::burn_address(false), None),
2967+
],
2968+
2969+
treatment: vec![],
2970+
sunset_burn: 0,
2971+
2972+
txid: Txid([0x00; 32]),
2973+
vtxindex: 0,
2974+
block_height: 2212,
2975+
burn_header_hash: BurnchainHeaderHash([0x01; 32]),
2976+
};
2977+
2978+
assert_eq!(to_hex(&commit_op.serialize_to_vec()), "5be88c3d30cb59a142f83de3b27f897a43bbb0f13316911bb98a3229973dae32afd5b9f21bc1f40f24e2c101ecd13c55b8619e5e03dad81de2c62a1cc1d8c1b375000008a300010000059800015a".to_string());
2979+
2980+
let leader_fees = LeaderBlockCommitFees {
2981+
sunset_fee: 0,
2982+
fee_rate: 50,
2983+
sortition_fee: 20000,
2984+
outputs_len: 2,
2985+
default_tx_size: 380,
2986+
spent_in_attempts: 0,
2987+
is_rbf_enabled: false,
2988+
final_size: 498,
2989+
};
2990+
2991+
assert_eq!(leader_fees.amount_per_output(), 10000);
2992+
assert_eq!(leader_fees.total_spent(), 44900);
2993+
2994+
let block_commit = btc_controller
2995+
.send_block_commit_operation_at_burnchain_height(
2996+
StacksEpochId::Epoch30,
2997+
commit_op,
2998+
&mut signer,
2999+
Some(utxo_set),
3000+
None,
3001+
leader_fees,
3002+
&vec![],
3003+
2212,
3004+
)
3005+
.unwrap();
3006+
3007+
debug!("send_block_commit_operation:\n{:#?}", &block_commit);
3008+
debug!("{}", &SerializedTx::new(block_commit.clone()).to_hex());
3009+
assert_eq!(block_commit.output[3].value, 323507);
3010+
3011+
assert_eq!(&SerializedTx::new(block_commit.clone()).to_hex(), "0100000002eeda098987728e4a2e21b34b74000dcb0bd0e4d20e55735492ec3cba3afbead3030000006a4730440220558286e20e10ce31537f0625dae5cc62fac7961b9d2cf272c990de96323d7e2502202255adbea3d2e0509b80c5d8a3a4fe6397a87bcf18da1852740d5267d89a0cb20121035379aa40c02890d253cfa577964116eb5295570ae9f7287cbae5f2585f5b2c7cfdffffff243b0b329a5889ab8801b315eea19810848d4c2133e0245671cc984a2d2f1301000000006a47304402206d9f8de107f9e1eb15aafac66c2bb34331a7523260b30e18779257e367048d34022013c7dabb32a5c281aa00d405e2ccbd00f34f03a65b2336553a4acd6c52c251ef0121035379aa40c02890d253cfa577964116eb5295570ae9f7287cbae5f2585f5b2c7cfdffffff040000000000000000536a4c5054335be88c3d30cb59a142f83de3b27f897a43bbb0f13316911bb98a3229973dae32afd5b9f21bc1f40f24e2c101ecd13c55b8619e5e03dad81de2c62a1cc1d8c1b375000008a300010000059800015a10270000000000001976a914000000000000000000000000000000000000000088ac10270000000000001976a914000000000000000000000000000000000000000088acb3ef0400000000001976a9141dc27eba0247f8cc9575e7d45e50a0bc7e72427d88ac00000000");
3012+
}
28283013
}

testnet/stacks-node/src/keychain.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ impl Keychain {
206206
}
207207

208208
/// Create a BurnchainOpSigner representation of this keychain
209-
/// (this is going to be removed in 2.1)
210209
pub fn generate_op_signer(&self) -> BurnchainOpSigner {
211210
BurnchainOpSigner::new(self.get_secret_key(), false)
212211
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12784,7 +12784,6 @@ fn mock_miner_replay() {
1278412784

1278512785
// ---------- Test finished, clean up ----------
1278612786

12787-
btcd_controller.stop_bitcoind().unwrap();
1278812787
miner_channel.stop_chains_coordinator();
1278912788
follower_channel.stop_chains_coordinator();
1279012789
}

0 commit comments

Comments
 (0)