@@ -696,6 +696,7 @@ impl TestStacksNode {
696
696
mut after_block : G ,
697
697
malleablize : bool ,
698
698
mined_canonical : bool ,
699
+ timestamp : Option < u64 > ,
699
700
) -> Result < Vec < ( NakamotoBlock , u64 , ExecutionCost , Vec < NakamotoBlock > ) > , ChainstateError >
700
701
where
701
702
S : FnMut ( & mut NakamotoBlockBuilder ) ,
@@ -804,6 +805,10 @@ impl TestStacksNode {
804
805
& coinbase. clone ( ) . unwrap ( ) ,
805
806
)
806
807
} ;
808
+ // Optionally overwrite the timestamp to enable predictable blocks.
809
+ if let Some ( timestamp) = timestamp {
810
+ builder. header . timestamp = timestamp;
811
+ }
807
812
miner_setup ( & mut builder) ;
808
813
809
814
tenure_change = None ;
@@ -1060,82 +1065,82 @@ impl TestStacksNode {
1060
1065
}
1061
1066
}
1062
1067
1063
- impl TestPeer < ' _ > {
1064
- /// Get the Nakamoto parent linkage data for building atop the last-produced tenure or
1065
- /// Stacks 2.x block.
1066
- /// Returns (last-tenure-id, epoch2-parent, nakamoto-parent-tenure, parent-sortition)
1067
- fn get_nakamoto_parent (
1068
- miner : & TestMiner ,
1069
- stacks_node : & TestStacksNode ,
1070
- sortdb : & SortitionDB ,
1071
- ) -> (
1072
- StacksBlockId ,
1073
- Option < StacksBlock > ,
1074
- Option < Vec < NakamotoBlock > > ,
1075
- ) {
1076
- let tip = SortitionDB :: get_canonical_burn_chain_tip ( sortdb. conn ( ) ) . unwrap ( ) ;
1077
- if let Some ( parent_blocks) = stacks_node. get_last_nakamoto_tenure ( miner) {
1078
- debug ! ( "Parent will be a Nakamoto block" ) ;
1079
-
1080
- // parent is an epoch 3 nakamoto block
1081
- let first_parent = parent_blocks. first ( ) . unwrap ( ) ;
1082
- debug ! ( "First parent is {:?}" , first_parent) ;
1068
+ /// Get the Nakamoto parent linkage data for building atop the last-produced tenure or
1069
+ /// Stacks 2.x block.
1070
+ /// Returns (last-tenure-id, epoch2-parent, nakamoto-parent-tenure, parent-sortition)
1071
+ pub fn get_nakamoto_parent (
1072
+ miner : & TestMiner ,
1073
+ stacks_node : & TestStacksNode ,
1074
+ sortdb : & SortitionDB ,
1075
+ ) -> (
1076
+ StacksBlockId ,
1077
+ Option < StacksBlock > ,
1078
+ Option < Vec < NakamotoBlock > > ,
1079
+ ) {
1080
+ let tip = SortitionDB :: get_canonical_burn_chain_tip ( sortdb. conn ( ) ) . unwrap ( ) ;
1081
+ if let Some ( parent_blocks) = stacks_node. get_last_nakamoto_tenure ( miner) {
1082
+ debug ! ( "Parent will be a Nakamoto block" ) ;
1083
+
1084
+ // parent is an epoch 3 nakamoto block
1085
+ let first_parent = parent_blocks. first ( ) . unwrap ( ) ;
1086
+ debug ! ( "First parent is {:?}" , first_parent) ;
1087
+
1088
+ // sanity check -- this parent must correspond to a sortition
1089
+ assert ! (
1090
+ SortitionDB :: get_block_snapshot_consensus(
1091
+ sortdb. conn( ) ,
1092
+ & first_parent. header. consensus_hash,
1093
+ )
1094
+ . unwrap( )
1095
+ . unwrap( )
1096
+ . sortition
1097
+ ) ;
1083
1098
1084
- // sanity check -- this parent must correspond to a sortition
1085
- assert ! (
1086
- SortitionDB :: get_block_snapshot_consensus(
1087
- sortdb. conn( ) ,
1088
- & first_parent. header. consensus_hash,
1089
- )
1090
- . unwrap( )
1091
- . unwrap( )
1092
- . sortition
1099
+ let last_tenure_id = StacksBlockId :: new (
1100
+ & first_parent. header . consensus_hash ,
1101
+ & first_parent. header . block_hash ( ) ,
1102
+ ) ;
1103
+ ( last_tenure_id, None , Some ( parent_blocks) )
1104
+ } else {
1105
+ // parent may be an epoch 2.x block
1106
+ let ( parent_opt, parent_sortition_opt) = if let Some ( parent_block) =
1107
+ stacks_node. get_last_anchored_block ( miner)
1108
+ {
1109
+ debug ! ( "Parent will be a Stacks 2.x block" ) ;
1110
+ let ic = sortdb. index_conn ( ) ;
1111
+ let sort_opt = SortitionDB :: get_block_snapshot_for_winning_stacks_block (
1112
+ & ic,
1113
+ & tip. sortition_id ,
1114
+ & parent_block. block_hash ( ) ,
1115
+ )
1116
+ . unwrap ( ) ;
1117
+ if sort_opt. is_none ( ) {
1118
+ warn ! ( "No parent sortition in epoch2: tip.sortition_id = {}, parent_block.block_hash() = {}" , & tip. sortition_id, & parent_block. block_hash( ) ) ;
1119
+ }
1120
+ ( Some ( parent_block) , sort_opt)
1121
+ } else {
1122
+ warn ! (
1123
+ "No parent sortition in epoch2: tip.sortition_id = {}" ,
1124
+ & tip. sortition_id
1093
1125
) ;
1126
+ ( None , None )
1127
+ } ;
1094
1128
1095
- let last_tenure_id = StacksBlockId :: new (
1096
- & first_parent. header . consensus_hash ,
1097
- & first_parent. header . block_hash ( ) ,
1098
- ) ;
1099
- ( last_tenure_id, None , Some ( parent_blocks) )
1129
+ let last_tenure_id = if let Some ( last_epoch2_block) = parent_opt. as_ref ( ) {
1130
+ let parent_sort = parent_sortition_opt. as_ref ( ) . unwrap ( ) ;
1131
+ StacksBlockId :: new (
1132
+ & parent_sort. consensus_hash ,
1133
+ & last_epoch2_block. header . block_hash ( ) ,
1134
+ )
1100
1135
} else {
1101
- // parent may be an epoch 2.x block
1102
- let ( parent_opt, parent_sortition_opt) = if let Some ( parent_block) =
1103
- stacks_node. get_last_anchored_block ( miner)
1104
- {
1105
- debug ! ( "Parent will be a Stacks 2.x block" ) ;
1106
- let ic = sortdb. index_conn ( ) ;
1107
- let sort_opt = SortitionDB :: get_block_snapshot_for_winning_stacks_block (
1108
- & ic,
1109
- & tip. sortition_id ,
1110
- & parent_block. block_hash ( ) ,
1111
- )
1112
- . unwrap ( ) ;
1113
- if sort_opt. is_none ( ) {
1114
- warn ! ( "No parent sortition in epoch2: tip.sortition_id = {}, parent_block.block_hash() = {}" , & tip. sortition_id, & parent_block. block_hash( ) ) ;
1115
- }
1116
- ( Some ( parent_block) , sort_opt)
1117
- } else {
1118
- warn ! (
1119
- "No parent sortition in epoch2: tip.sortition_id = {}" ,
1120
- & tip. sortition_id
1121
- ) ;
1122
- ( None , None )
1123
- } ;
1124
-
1125
- let last_tenure_id = if let Some ( last_epoch2_block) = parent_opt. as_ref ( ) {
1126
- let parent_sort = parent_sortition_opt. as_ref ( ) . unwrap ( ) ;
1127
- StacksBlockId :: new (
1128
- & parent_sort. consensus_hash ,
1129
- & last_epoch2_block. header . block_hash ( ) ,
1130
- )
1131
- } else {
1132
- // must be a genesis block (testing only!)
1133
- StacksBlockId ( BOOT_BLOCK_HASH . 0 )
1134
- } ;
1135
- ( last_tenure_id, parent_opt, None )
1136
- }
1136
+ // must be a genesis block (testing only!)
1137
+ StacksBlockId ( BOOT_BLOCK_HASH . 0 )
1138
+ } ;
1139
+ ( last_tenure_id, parent_opt, None )
1137
1140
}
1141
+ }
1138
1142
1143
+ impl TestPeer < ' _ > {
1139
1144
/// Start the next Nakamoto tenure.
1140
1145
/// This generates the VRF key and block-commit txs, as well as the TenureChange and
1141
1146
/// leader key this commit references
@@ -1161,7 +1166,7 @@ impl TestPeer<'_> {
1161
1166
Some ( nakamoto_parent_tenure. clone ( ) ) ,
1162
1167
)
1163
1168
} else {
1164
- Self :: get_nakamoto_parent ( & self . miner , & stacks_node, & sortdb)
1169
+ get_nakamoto_parent ( & self . miner , & stacks_node, & sortdb)
1165
1170
} ;
1166
1171
1167
1172
// find the VRF leader key register tx to use.
@@ -1464,6 +1469,7 @@ impl TestPeer<'_> {
1464
1469
after_block,
1465
1470
peer. mine_malleablized_blocks ,
1466
1471
peer. nakamoto_parent_tenure_opt . is_none ( ) ,
1472
+ None ,
1467
1473
) ?;
1468
1474
1469
1475
let just_blocks = blocks
@@ -1552,6 +1558,7 @@ impl TestPeer<'_> {
1552
1558
|_| true ,
1553
1559
self . mine_malleablized_blocks ,
1554
1560
self . nakamoto_parent_tenure_opt . is_none ( ) ,
1561
+ None ,
1555
1562
)
1556
1563
. unwrap ( ) ;
1557
1564
0 commit comments