Skip to content

Commit 949c149

Browse files
authored
Merge branch 'develop' into fix/event-dispatcher-timeout
2 parents 1844033 + f16beb3 commit 949c149

File tree

4 files changed

+213
-8
lines changed

4 files changed

+213
-8
lines changed

.github/workflows/pr-differences-mutants.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,34 @@ on:
99
- ready_for_review
1010
paths:
1111
- '**.rs'
12+
workflow_dispatch:
1213

1314
concurrency:
1415
group: pr-differences-${{ github.head_ref || github.ref || github.run_id }}
1516
# Always cancel duplicate jobs
1617
cancel-in-progress: true
1718

1819
jobs:
20+
check-access-permissions:
21+
name: Check Access Permissions
22+
runs-on: ubuntu-latest
23+
24+
steps:
25+
- name: Check Access Permissions To Trigger This
26+
id: check_access_permissions
27+
uses: stacks-network/actions/team-membership@main
28+
with:
29+
username: ${{ github.actor }}
30+
team: 'blockchain-team'
31+
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
32+
33+
outputs:
34+
ignore_timeout: ${{ steps.check_access_permissions.outputs.is_team_member == 'true' && github.event_name == 'workflow_dispatch' }}
35+
1936
# Check and output whether to run big (`stacks-node`/`stackslib`) or small (others) packages with or without shards
2037
check-big-packages-and-shards:
2138
name: Check Packages and Shards
39+
needs: check-access-permissions
2240

2341
runs-on: ubuntu-latest
2442

@@ -30,10 +48,13 @@ jobs:
3048
run_small_packages: ${{ steps.check_packages_and_shards.outputs.run_small_packages }}
3149
small_packages_with_shards: ${{ steps.check_packages_and_shards.outputs.small_packages_with_shards }}
3250
run_stacks_signer: ${{ steps.check_packages_and_shards.outputs.run_stacks_signer }}
51+
too_many_mutants: ${{ steps.check_packages_and_shards.outputs.too_many_mutants }}
3352

3453
steps:
3554
- id: check_packages_and_shards
3655
uses: stacks-network/actions/stacks-core/mutation-testing/check-packages-and-shards@main
56+
with:
57+
ignore_timeout: ${{ needs.check-access-permissions.outputs.ignore_timeout }}
3758

3859
# Mutation testing - Execute on PR on small packages that have functions modified (normal run, no shards)
3960
pr-differences-mutants-small-normal:
@@ -220,3 +241,4 @@ jobs:
220241
small_packages: ${{ needs.check-big-packages-and-shards.outputs.run_small_packages }}
221242
shards_for_small_packages: ${{ needs.check-big-packages-and-shards.outputs.small_packages_with_shards }}
222243
stacks_signer: ${{ needs.check-big-packages-and-shards.outputs.run_stacks_signer }}
244+
too_many_mutants: ${{ needs.check-big-packages-and-shards.outputs.too_many_mutants }}

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

Lines changed: 191 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,22 +1376,44 @@ impl BitcoinRegtestController {
13761376
previous_fees: Option<LeaderBlockCommitFees>,
13771377
previous_txids: &Vec<Txid>,
13781378
) -> Option<Transaction> {
1379-
let mut estimated_fees = match previous_fees {
1379+
let _ = self.sortdb_mut();
1380+
let burn_chain_tip = self.burnchain_db.as_ref()?.get_canonical_chain_tip().ok()?;
1381+
let estimated_fees = match previous_fees {
13801382
Some(fees) => fees.fees_from_previous_tx(&payload, &self.config),
13811383
None => LeaderBlockCommitFees::estimated_fees_from_payload(&payload, &self.config),
13821384
};
13831385

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

1398+
fn send_block_commit_operation_at_burnchain_height(
1399+
&mut self,
1400+
epoch_id: StacksEpochId,
1401+
payload: LeaderBlockCommitOp,
1402+
signer: &mut BurnchainOpSigner,
1403+
utxos_to_include: Option<UTXOSet>,
1404+
utxos_to_exclude: Option<UTXOSet>,
1405+
mut estimated_fees: LeaderBlockCommitFees,
1406+
previous_txids: &Vec<Txid>,
1407+
burnchain_block_height: u64,
1408+
) -> Option<Transaction> {
13871409
let public_key = signer.get_public_key();
13881410
let (mut tx, mut utxos) = self.prepare_tx(
13891411
epoch_id,
13901412
&public_key,
13911413
estimated_fees.estimated_amount_required(),
13921414
utxos_to_include,
13931415
utxos_to_exclude,
1394-
burn_chain_tip.block_height,
1416+
burnchain_block_height,
13951417
)?;
13961418

13971419
// Serialize the payload
@@ -1820,7 +1842,7 @@ impl BitcoinRegtestController {
18201842
debug!("Not enough change to clear dust limit. Not adding change address.");
18211843
}
18221844

1823-
for (i, utxo) in utxos_set.utxos.iter().enumerate() {
1845+
for (_i, utxo) in utxos_set.utxos.iter().enumerate() {
18241846
let input = TxIn {
18251847
previous_output: OutPoint {
18261848
txid: utxo.txid,
@@ -1831,7 +1853,8 @@ impl BitcoinRegtestController {
18311853
witness: vec![],
18321854
};
18331855
tx.input.push(input);
1834-
1856+
}
1857+
for (i, utxo) in utxos_set.utxos.iter().enumerate() {
18351858
let script_pub_key = utxo.script_pub_key.clone();
18361859
let sig_hash_all = 0x01;
18371860

@@ -2786,6 +2809,12 @@ mod tests {
27862809
use std::fs::File;
27872810
use std::io::Write;
27882811

2812+
use stacks::burnchains::BurnchainSigner;
2813+
use stacks_common::deps_common::bitcoin::blockdata::script::Builder;
2814+
use stacks_common::types::chainstate::{BlockHeaderHash, StacksAddress, VRFSeed};
2815+
use stacks_common::util::hash::to_hex;
2816+
use stacks_common::util::secp256k1::Secp256k1PrivateKey;
2817+
27892818
use super::*;
27902819
use crate::config::DEFAULT_SATS_PER_VB;
27912820

@@ -2806,4 +2835,160 @@ mod tests {
28062835

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

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)