@@ -57,7 +57,11 @@ use stacks_common::util::sleep_ms;
57
57
use super :: super :: operations:: BurnchainOpSigner ;
58
58
use super :: super :: Config ;
59
59
use super :: { BurnchainController , BurnchainTip , Error as BurnchainControllerError } ;
60
- use crate :: config:: BurnchainConfig ;
60
+ use crate :: config:: {
61
+ BurnchainConfig , OP_TX_ANY_ESTIM_SIZE , OP_TX_DELEGATE_STACKS_ESTIM_SIZE ,
62
+ OP_TX_PRE_STACKS_ESTIM_SIZE , OP_TX_STACK_STX_ESTIM_SIZE , OP_TX_TRANSFER_STACKS_ESTIM_SIZE ,
63
+ OP_TX_VOTE_AGG_ESTIM_SIZE ,
64
+ } ;
61
65
62
66
/// The number of bitcoin blocks that can have
63
67
/// passed since the UTXO cache was last refreshed before
@@ -868,6 +872,7 @@ impl BitcoinRegtestController {
868
872
fee_rate,
869
873
& mut utxos,
870
874
signer,
875
+ false ,
871
876
) ?;
872
877
873
878
increment_btc_ops_sent_counter ( ) ;
@@ -950,7 +955,7 @@ impl BitcoinRegtestController {
950
955
utxo_to_use : Option < UTXO > ,
951
956
) -> Option < Transaction > {
952
957
let public_key = signer. get_public_key ( ) ;
953
- let max_tx_size = 230 ;
958
+ let max_tx_size = OP_TX_TRANSFER_STACKS_ESTIM_SIZE ;
954
959
let ( mut tx, mut utxos) = if let Some ( utxo) = utxo_to_use {
955
960
(
956
961
Transaction {
@@ -1005,6 +1010,7 @@ impl BitcoinRegtestController {
1005
1010
get_satoshis_per_byte ( & self . config ) ,
1006
1011
& mut utxos,
1007
1012
signer,
1013
+ false ,
1008
1014
) ?;
1009
1015
1010
1016
increment_btc_ops_sent_counter ( ) ;
@@ -1032,7 +1038,7 @@ impl BitcoinRegtestController {
1032
1038
utxo_to_use : Option < UTXO > ,
1033
1039
) -> Option < Transaction > {
1034
1040
let public_key = signer. get_public_key ( ) ;
1035
- let max_tx_size = 230 ;
1041
+ let max_tx_size = OP_TX_DELEGATE_STACKS_ESTIM_SIZE ;
1036
1042
1037
1043
let ( mut tx, mut utxos) = if let Some ( utxo) = utxo_to_use {
1038
1044
(
@@ -1088,6 +1094,7 @@ impl BitcoinRegtestController {
1088
1094
get_satoshis_per_byte ( & self . config ) ,
1089
1095
& mut utxos,
1090
1096
signer,
1097
+ false ,
1091
1098
) ?;
1092
1099
1093
1100
increment_btc_ops_sent_counter ( ) ;
@@ -1110,7 +1117,7 @@ impl BitcoinRegtestController {
1110
1117
utxo_to_use : Option < UTXO > ,
1111
1118
) -> Option < Transaction > {
1112
1119
let public_key = signer. get_public_key ( ) ;
1113
- let max_tx_size = 230 ;
1120
+ let max_tx_size = OP_TX_VOTE_AGG_ESTIM_SIZE ;
1114
1121
1115
1122
let ( mut tx, mut utxos) = if let Some ( utxo) = utxo_to_use {
1116
1123
(
@@ -1162,6 +1169,7 @@ impl BitcoinRegtestController {
1162
1169
get_satoshis_per_byte ( & self . config ) ,
1163
1170
& mut utxos,
1164
1171
signer,
1172
+ false ,
1165
1173
) ?;
1166
1174
1167
1175
increment_btc_ops_sent_counter ( ) ;
@@ -1204,9 +1212,11 @@ impl BitcoinRegtestController {
1204
1212
signer : & mut BurnchainOpSigner ,
1205
1213
) -> Option < Transaction > {
1206
1214
let public_key = signer. get_public_key ( ) ;
1207
- let max_tx_size = 280 ;
1215
+ let max_tx_size = OP_TX_PRE_STACKS_ESTIM_SIZE ;
1216
+
1217
+ let max_tx_size_any_op = OP_TX_ANY_ESTIM_SIZE ;
1218
+ let output_amt = DUST_UTXO_LIMIT + max_tx_size_any_op * get_satoshis_per_byte ( & self . config ) ;
1208
1219
1209
- let output_amt = DUST_UTXO_LIMIT + max_tx_size * get_satoshis_per_byte ( & self . config ) ;
1210
1220
let ( mut tx, mut utxos) =
1211
1221
self . prepare_tx ( epoch_id, & public_key, output_amt, None , None , 0 ) ?;
1212
1222
@@ -1238,6 +1248,7 @@ impl BitcoinRegtestController {
1238
1248
get_satoshis_per_byte ( & self . config ) ,
1239
1249
& mut utxos,
1240
1250
signer,
1251
+ false ,
1241
1252
) ?;
1242
1253
1243
1254
increment_btc_ops_sent_counter ( ) ;
@@ -1271,7 +1282,7 @@ impl BitcoinRegtestController {
1271
1282
utxo_to_use : Option < UTXO > ,
1272
1283
) -> Option < Transaction > {
1273
1284
let public_key = signer. get_public_key ( ) ;
1274
- let max_tx_size = 250 ;
1285
+ let max_tx_size = OP_TX_STACK_STX_ESTIM_SIZE ;
1275
1286
1276
1287
let ( mut tx, mut utxos) = if let Some ( utxo) = utxo_to_use {
1277
1288
(
@@ -1325,6 +1336,7 @@ impl BitcoinRegtestController {
1325
1336
get_satoshis_per_byte ( & self . config ) ,
1326
1337
& mut utxos,
1327
1338
signer,
1339
+ false ,
1328
1340
) ?;
1329
1341
1330
1342
increment_btc_ops_sent_counter ( ) ;
@@ -1415,6 +1427,7 @@ impl BitcoinRegtestController {
1415
1427
fee_rate,
1416
1428
& mut utxos,
1417
1429
signer,
1430
+ true , // only block commit op requires change output to exist
1418
1431
) ?;
1419
1432
1420
1433
let serialized_tx = SerializedTx :: new ( tx. clone ( ) ) ;
@@ -1685,6 +1698,7 @@ impl BitcoinRegtestController {
1685
1698
fee_rate : u64 ,
1686
1699
utxos_set : & mut UTXOSet ,
1687
1700
signer : & mut BurnchainOpSigner ,
1701
+ force_change_output : bool ,
1688
1702
) -> Option < ( ) > {
1689
1703
// spend UTXOs in order by confirmations. Spend the least-confirmed UTXO first, and in the
1690
1704
// event of a tie, spend the smallest-value UTXO first.
@@ -1715,6 +1729,7 @@ impl BitcoinRegtestController {
1715
1729
spent_in_outputs + min_tx_size * fee_rate + estimated_rbf,
1716
1730
& mut utxos_cloned,
1717
1731
signer,
1732
+ force_change_output,
1718
1733
) ;
1719
1734
let serialized_tx = SerializedTx :: new ( tx_cloned) ;
1720
1735
cmp:: max ( min_tx_size, serialized_tx. bytes . len ( ) as u64 )
@@ -1731,6 +1746,7 @@ impl BitcoinRegtestController {
1731
1746
spent_in_outputs + tx_size * fee_rate + rbf_fee,
1732
1747
utxos_set,
1733
1748
signer,
1749
+ force_change_output,
1734
1750
) ;
1735
1751
signer. dispose ( ) ;
1736
1752
Some ( ( ) )
@@ -1744,38 +1760,45 @@ impl BitcoinRegtestController {
1744
1760
& mut self ,
1745
1761
epoch_id : StacksEpochId ,
1746
1762
tx : & mut Transaction ,
1747
- total_to_spend : u64 ,
1763
+ tx_cost : u64 ,
1748
1764
utxos_set : & mut UTXOSet ,
1749
1765
signer : & mut BurnchainOpSigner ,
1766
+ force_change_output : bool ,
1750
1767
) -> bool {
1751
1768
let mut public_key = signer. get_public_key ( ) ;
1752
- let mut total_consumed = 0 ;
1769
+
1770
+ let total_target = if force_change_output {
1771
+ tx_cost + DUST_UTXO_LIMIT
1772
+ } else {
1773
+ tx_cost
1774
+ } ;
1753
1775
1754
1776
// select UTXOs until we have enough to cover the cost
1777
+ let mut total_consumed = 0 ;
1755
1778
let mut available_utxos = vec ! [ ] ;
1756
1779
available_utxos. append ( & mut utxos_set. utxos ) ;
1757
1780
for utxo in available_utxos. into_iter ( ) {
1758
1781
total_consumed += utxo. amount ;
1759
1782
utxos_set. utxos . push ( utxo) ;
1760
1783
1761
- if total_consumed >= total_to_spend {
1784
+ if total_consumed >= total_target {
1762
1785
break ;
1763
1786
}
1764
1787
}
1765
1788
1766
- if total_consumed < total_to_spend {
1789
+ if total_consumed < total_target {
1767
1790
warn ! (
1768
1791
"Consumed total {} is less than intended spend: {}" ,
1769
- total_consumed, total_to_spend
1792
+ total_consumed, total_target
1770
1793
) ;
1771
1794
return false ;
1772
1795
}
1773
1796
1774
1797
// Append the change output
1775
- let value = total_consumed - total_to_spend ;
1798
+ let value = total_consumed - tx_cost ;
1776
1799
debug ! (
1777
1800
"Payments value: {:?}, total_consumed: {:?}, total_spent: {:?}" ,
1778
- value, total_consumed, total_to_spend
1801
+ value, total_consumed, total_target
1779
1802
) ;
1780
1803
if value >= DUST_UTXO_LIMIT {
1781
1804
let change_output = if self . config . miner . segwit && epoch_id >= StacksEpochId :: Epoch21 {
0 commit comments