@@ -30,6 +30,7 @@ use {serde, serde_json};
30
30
use crate :: chainstate:: burn:: db:: sortdb:: SortitionDB ;
31
31
use crate :: chainstate:: burn:: BlockSnapshot ;
32
32
use crate :: chainstate:: nakamoto:: { NakamotoBlock , NakamotoChainState , NakamotoStagingBlocksConn } ;
33
+ use crate :: chainstate:: nakamoto:: StacksDBIndexed ;
33
34
use crate :: chainstate:: stacks:: db:: StacksChainState ;
34
35
use crate :: chainstate:: stacks:: Error as ChainError ;
35
36
use crate :: net:: api:: getblock_v3:: NakamotoBlockStream ;
@@ -85,6 +86,11 @@ pub struct SortitionInfo {
85
86
pub consensus_hash : ConsensusHash ,
86
87
/// Boolean indicating whether or not there was a succesful sortition (i.e. a winning
87
88
/// block or miner was chosen).
89
+ ///
90
+ /// This will *also* be true if this sortition corresponds to a shadow block. This is because
91
+ /// the signer does not distinguish between shadow blocks and blocks with sortitions, so until
92
+ /// we can update the signer and this interface, we'll have to report the presence of a shadow
93
+ /// block tenure in a way that the signer currently understands.
88
94
pub was_sortition : bool ,
89
95
/// If sortition occurred, and the miner's VRF key registration
90
96
/// associated a nakamoto mining pubkey with their commit, this
@@ -150,13 +156,25 @@ impl GetSortitionHandler {
150
156
fn get_sortition_info (
151
157
sortition_sn : BlockSnapshot ,
152
158
sortdb : & SortitionDB ,
159
+ chainstate : & mut StacksChainState ,
160
+ tip : & StacksBlockId
153
161
) -> Result < SortitionInfo , ChainError > {
162
+ let is_shadow = chainstate. nakamoto_blocks_db ( ) . is_shadow_tenure ( & sortition_sn. consensus_hash ) ?;
154
163
let ( miner_pk_hash160, stacks_parent_ch, committed_block_hash, last_sortition_ch) =
155
- if !sortition_sn. sortition {
164
+ if !sortition_sn. sortition && !is_shadow {
156
165
let handle = sortdb. index_handle ( & sortition_sn. sortition_id ) ;
157
166
let last_sortition =
158
167
handle. get_last_snapshot_with_sortition ( sortition_sn. block_height ) ?;
159
168
( None , None , None , Some ( last_sortition. consensus_hash ) )
169
+ } else if !sortition_sn. sortition && is_shadow {
170
+ // this is a shadow tenure.
171
+ let parent_tenure_ch = chainstate. index_conn ( ) . get_parent_tenure_consensus_hash ( tip, & sortition_sn. consensus_hash ) ?
172
+ . ok_or_else ( || DBError :: NotFoundError ) ?;
173
+
174
+ let parent_tenure_start_header = NakamotoChainState :: get_nakamoto_tenure_start_block_header ( & mut chainstate. index_conn ( ) , tip, & parent_tenure_ch) ?
175
+ . ok_or_else ( || DBError :: NotFoundError ) ?;
176
+
177
+ ( Some ( Hash160 ( [ 0x00 ; 20 ] ) ) , Some ( parent_tenure_ch. clone ( ) ) , Some ( BlockHeaderHash ( parent_tenure_start_header. index_block_hash ( ) . 0 ) ) , Some ( parent_tenure_ch) )
160
178
} else {
161
179
let block_commit = SortitionDB :: get_block_commit ( sortdb. conn ( ) , & sortition_sn. winning_block_txid , & sortition_sn. sortition_id ) ?
162
180
. ok_or_else ( || {
@@ -211,7 +229,7 @@ impl GetSortitionHandler {
211
229
sortition_id : sortition_sn. sortition_id ,
212
230
parent_sortition_id : sortition_sn. parent_sortition_id ,
213
231
consensus_hash : sortition_sn. consensus_hash ,
214
- was_sortition : sortition_sn. sortition ,
232
+ was_sortition : sortition_sn. sortition || is_shadow ,
215
233
miner_pk_hash160,
216
234
stacks_parent_ch,
217
235
last_sortition_ch,
@@ -277,7 +295,7 @@ impl RPCRequestHandler for GetSortitionHandler {
277
295
_contents : HttpRequestContents ,
278
296
node : & mut StacksNodeState ,
279
297
) -> Result < ( HttpResponsePreamble , HttpResponseContents ) , NetError > {
280
- let result = node. with_node_state ( |network, sortdb, _chainstate , _mempool, _rpc_args| {
298
+ let result = node. with_node_state ( |network, sortdb, chainstate , _mempool, _rpc_args| {
281
299
let query_result = match self . query {
282
300
QuerySpecifier :: Latest => Ok ( Some ( network. burnchain_tip . clone ( ) ) ) ,
283
301
QuerySpecifier :: ConsensusHash ( ref consensus_hash) => {
@@ -306,7 +324,7 @@ impl RPCRequestHandler for GetSortitionHandler {
306
324
}
307
325
} ;
308
326
let sortition_sn = query_result?. ok_or_else ( || ChainError :: NoSuchBlockError ) ?;
309
- Self :: get_sortition_info ( sortition_sn, sortdb)
327
+ Self :: get_sortition_info ( sortition_sn, sortdb, chainstate , & network . stacks_tip . block_id ( ) )
310
328
} ) ;
311
329
312
330
let block = match result {
@@ -334,13 +352,13 @@ impl RPCRequestHandler for GetSortitionHandler {
334
352
if self . query == QuerySpecifier :: LatestAndLast {
335
353
// if latest **and** last are requested, lookup the sortition info for last_sortition_ch
336
354
if let Some ( last_sortition_ch) = last_sortition_ch {
337
- let result = node. with_node_state ( |_ , sortdb, _ , _, _| {
355
+ let result = node. with_node_state ( |network , sortdb, chainstate , _, _| {
338
356
let last_sortition_sn = SortitionDB :: get_block_snapshot_consensus (
339
357
sortdb. conn ( ) ,
340
358
& last_sortition_ch,
341
359
) ?
342
360
. ok_or_else ( || ChainError :: NoSuchBlockError ) ?;
343
- Self :: get_sortition_info ( last_sortition_sn, sortdb)
361
+ Self :: get_sortition_info ( last_sortition_sn, sortdb, chainstate , & network . stacks_tip . block_id ( ) )
344
362
} ) ;
345
363
let last_block = match result {
346
364
Ok ( block) => block,
0 commit comments