@@ -72,6 +72,10 @@ impl std::fmt::Display for SignerSlotID {
72
72
pub struct BlockInfo {
73
73
/// The block we are considering
74
74
pub block : NakamotoBlock ,
75
+ /// The burn block height at which the block was proposed
76
+ pub burn_block_height : u64 ,
77
+ /// The reward cycle the block belongs to
78
+ pub reward_cycle : u64 ,
75
79
/// Our vote on the block if we have one yet
76
80
pub vote : Option < NakamotoBlockVote > ,
77
81
/// Whether the block contents are valid
@@ -82,27 +86,29 @@ pub struct BlockInfo {
82
86
pub signed_over : bool ,
83
87
}
84
88
85
- impl BlockInfo {
86
- /// Create a new BlockInfo
87
- pub const fn new ( block : NakamotoBlock ) -> Self {
89
+ impl From < BlockProposalSigners > for BlockInfo {
90
+ fn from ( value : BlockProposalSigners ) -> Self {
88
91
Self {
89
- block,
92
+ block : value. block ,
93
+ burn_block_height : value. burn_height ,
94
+ reward_cycle : value. reward_cycle ,
90
95
vote : None ,
91
96
valid : None ,
92
97
nonce_request : None ,
93
98
signed_over : false ,
94
99
}
95
100
}
96
-
101
+ }
102
+ impl BlockInfo {
97
103
/// Create a new BlockInfo with an associated nonce request packet
98
- pub const fn new_with_request ( block : NakamotoBlock , nonce_request : NonceRequest ) -> Self {
99
- Self {
100
- block ,
101
- vote : None ,
102
- valid : None ,
103
- nonce_request : Some ( nonce_request) ,
104
- signed_over : true ,
105
- }
104
+ pub fn new_with_request (
105
+ block_proposal : BlockProposalSigners ,
106
+ nonce_request : NonceRequest ,
107
+ ) -> Self {
108
+ let mut block_info = BlockInfo :: from ( block_proposal ) ;
109
+ block_info . nonce_request = Some ( nonce_request) ;
110
+ block_info . signed_over = true ;
111
+ block_info
106
112
}
107
113
108
114
/// Return the block's signer signature hash
@@ -119,7 +125,7 @@ pub enum Command {
119
125
/// Sign a message
120
126
Sign {
121
127
/// The block to sign over
122
- block : NakamotoBlock ,
128
+ block_proposal : BlockProposalSigners ,
123
129
/// Whether to make a taproot signature
124
130
is_taproot : bool ,
125
131
/// Taproot merkle root
@@ -399,31 +405,31 @@ impl Signer {
399
405
}
400
406
}
401
407
Command :: Sign {
402
- block ,
408
+ block_proposal ,
403
409
is_taproot,
404
410
merkle_root,
405
411
} => {
406
412
if self . approved_aggregate_public_key . is_none ( ) {
407
413
debug ! ( "{self}: Cannot sign a block without an approved aggregate public key. Ignore it." ) ;
408
414
return ;
409
415
}
410
- let signer_signature_hash = block. header . signer_signature_hash ( ) ;
416
+ let signer_signature_hash = block_proposal . block . header . signer_signature_hash ( ) ;
411
417
let mut block_info = self
412
418
. signer_db
413
419
. block_lookup ( self . reward_cycle , & signer_signature_hash)
414
- . unwrap_or_else ( |_| Some ( BlockInfo :: new ( block . clone ( ) ) ) )
415
- . unwrap_or_else ( || BlockInfo :: new ( block . clone ( ) ) ) ;
420
+ . unwrap_or_else ( |_| Some ( BlockInfo :: from ( block_proposal . clone ( ) ) ) )
421
+ . unwrap_or_else ( || BlockInfo :: from ( block_proposal . clone ( ) ) ) ;
416
422
if block_info. signed_over {
417
423
debug ! ( "{self}: Received a sign command for a block we are already signing over. Ignore it." ) ;
418
424
return ;
419
425
}
420
426
info ! ( "{self}: Signing block" ;
421
- "block_consensus_hash" => %block. header. consensus_hash,
422
- "block_height" => block. header. chain_length,
423
- "pre_sign_block_id" => %block. block_id( ) ,
427
+ "block_consensus_hash" => %block_proposal . block. header. consensus_hash,
428
+ "block_height" => block_proposal . block. header. chain_length,
429
+ "pre_sign_block_id" => %block_proposal . block. block_id( ) ,
424
430
) ;
425
431
match self . coordinator . start_signing_round (
426
- & block . serialize_to_vec ( ) ,
432
+ & block_proposal . serialize_to_vec ( ) ,
427
433
* is_taproot,
428
434
* merkle_root,
429
435
) {
@@ -432,7 +438,7 @@ impl Signer {
432
438
debug ! ( "{self}: ACK: {ack:?}" , ) ;
433
439
block_info. signed_over = true ;
434
440
self . signer_db
435
- . insert_block ( self . reward_cycle , & block_info)
441
+ . insert_block ( & block_info)
436
442
. unwrap_or_else ( |e| {
437
443
error ! ( "{self}: Failed to insert block in DB: {e:?}" ) ;
438
444
} ) ;
@@ -517,7 +523,7 @@ impl Signer {
517
523
let is_valid = self . verify_block_transactions ( stacks_client, & block_info. block ) ;
518
524
block_info. valid = Some ( is_valid) ;
519
525
self . signer_db
520
- . insert_block ( self . reward_cycle , & block_info)
526
+ . insert_block ( & block_info)
521
527
. unwrap_or_else ( |_| panic ! ( "{self}: Failed to insert block in DB" ) ) ;
522
528
info ! (
523
529
"{self}: Treating block validation for block {} as valid: {:?}" ,
@@ -574,7 +580,7 @@ impl Signer {
574
580
"signed_over" => block_info. signed_over,
575
581
) ;
576
582
self . signer_db
577
- . insert_block ( self . reward_cycle , & block_info)
583
+ . insert_block ( & block_info)
578
584
. unwrap_or_else ( |_| panic ! ( "{self}: Failed to insert block in DB" ) ) ;
579
585
}
580
586
@@ -607,63 +613,6 @@ impl Signer {
607
613
self . handle_packets ( stacks_client, res, & packets, current_reward_cycle) ;
608
614
}
609
615
610
- /// Handle proposed blocks submitted by the miners to stackerdb
611
- fn handle_proposed_blocks (
612
- & mut self ,
613
- stacks_client : & StacksClient ,
614
- proposals : & [ BlockProposalSigners ] ,
615
- ) {
616
- for proposal in proposals {
617
- if proposal. reward_cycle != self . reward_cycle {
618
- debug ! (
619
- "{self}: Received proposal for block outside of my reward cycle, ignoring." ;
620
- "proposal_reward_cycle" => proposal. reward_cycle,
621
- "proposal_burn_height" => proposal. burn_height,
622
- ) ;
623
- continue ;
624
- }
625
- let sig_hash = proposal. block . header . signer_signature_hash ( ) ;
626
- match self . signer_db . block_lookup ( self . reward_cycle , & sig_hash) {
627
- Ok ( Some ( block) ) => {
628
- debug ! (
629
- "{self}: Received proposal for block already known, ignoring new proposal." ;
630
- "signer_sighash" => %sig_hash,
631
- "proposal_burn_height" => proposal. burn_height,
632
- "vote" => ?block. vote. as_ref( ) . map( |v| {
633
- if v. rejected {
634
- "REJECT"
635
- } else {
636
- "ACCEPT"
637
- }
638
- } ) ,
639
- "signed_over" => block. signed_over,
640
- ) ;
641
- continue ;
642
- }
643
- Ok ( None ) => {
644
- // Store the block in our cache
645
- self . signer_db
646
- . insert_block ( self . reward_cycle , & BlockInfo :: new ( proposal. block . clone ( ) ) )
647
- . unwrap_or_else ( |e| {
648
- error ! ( "{self}: Failed to insert block in DB: {e:?}" ) ;
649
- } ) ;
650
- // Submit the block for validation
651
- stacks_client
652
- . submit_block_for_validation ( proposal. block . clone ( ) )
653
- . unwrap_or_else ( |e| {
654
- warn ! ( "{self}: Failed to submit block for validation: {e:?}" ) ;
655
- } ) ;
656
- }
657
- Err ( e) => {
658
- error ! (
659
- "{self}: Failed to lookup block in DB: {e:?}. Dropping proposal request."
660
- ) ;
661
- continue ;
662
- }
663
- }
664
- }
665
- }
666
-
667
616
/// Helper function for determining if the provided message is a DKG specific message
668
617
fn is_dkg_message ( msg : & Message ) -> bool {
669
618
matches ! (
@@ -808,26 +757,35 @@ impl Signer {
808
757
stacks_client : & StacksClient ,
809
758
nonce_request : & mut NonceRequest ,
810
759
) -> Option < BlockInfo > {
811
- let Some ( block ) =
812
- NakamotoBlock :: consensus_deserialize ( & mut nonce_request. message . as_slice ( ) ) . ok ( )
760
+ let Some ( block_proposal ) =
761
+ BlockProposalSigners :: consensus_deserialize ( & mut nonce_request. message . as_slice ( ) ) . ok ( )
813
762
else {
814
- // We currently reject anything that is not a block
763
+ // We currently reject anything that is not a valid block proposal
815
764
warn ! ( "{self}: Received a nonce request for an unknown message stream. Reject it." , ) ;
816
765
return None ;
817
766
} ;
818
- let signer_signature_hash = block. header . signer_signature_hash ( ) ;
767
+ if block_proposal. reward_cycle != self . reward_cycle {
768
+ // We are not signing for this reward cycle. Reject the block
769
+ warn ! (
770
+ "{self}: Received a nonce request for a different reward cycle. Reject it." ;
771
+ "requested_reward_cycle" => block_proposal. reward_cycle,
772
+ ) ;
773
+ return None ;
774
+ }
775
+ // TODO: could add a check to ignore an old burn block height if we know its oudated. Would require us to store the burn block height we last saw on the side.
776
+ let signer_signature_hash = block_proposal. block . header . signer_signature_hash ( ) ;
819
777
let Some ( mut block_info) = self
820
778
. signer_db
821
779
. block_lookup ( self . reward_cycle , & signer_signature_hash)
822
780
. expect ( "Failed to connect to signer DB" )
823
781
else {
824
782
debug ! (
825
- "{self}: We have received a block sign request for a block we have not seen before. Cache the nonce request and submit the block for validation... " ;
826
- "signer_sighash" => %block . header . signer_signature_hash( ) ,
783
+ "{self}: received a nonce request for a new block. Submit block for validation. " ;
784
+ "signer_sighash" => %signer_signature_hash,
827
785
) ;
828
- let block_info = BlockInfo :: new_with_request ( block . clone ( ) , nonce_request. clone ( ) ) ;
786
+ let block_info = BlockInfo :: new_with_request ( block_proposal , nonce_request. clone ( ) ) ;
829
787
stacks_client
830
- . submit_block_for_validation ( block)
788
+ . submit_block_for_validation ( block_info . block . clone ( ) )
831
789
. unwrap_or_else ( |e| {
832
790
warn ! ( "{self}: Failed to submit block for validation: {e:?}" , ) ;
833
791
} ) ;
@@ -1000,7 +958,7 @@ impl Signer {
1000
958
return None ;
1001
959
} ;
1002
960
self . signer_db
1003
- . insert_block ( self . reward_cycle , & updated_block_info)
961
+ . insert_block ( & updated_block_info)
1004
962
. unwrap_or_else ( |_| panic ! ( "{self}: Failed to insert block in DB" ) ) ;
1005
963
let process_request = updated_block_info. vote . is_some ( ) ;
1006
964
if !process_request {
@@ -1533,7 +1491,7 @@ impl Signer {
1533
1491
) ;
1534
1492
self . handle_signer_messages ( stacks_client, res, messages, current_reward_cycle) ;
1535
1493
}
1536
- Some ( SignerEvent :: MinerMessages ( blocks , messages, miner_key) ) => {
1494
+ Some ( SignerEvent :: MinerMessages ( messages, miner_key) ) => {
1537
1495
if let Some ( miner_key) = miner_key {
1538
1496
let miner_key = PublicKey :: try_from ( miner_key. to_bytes_compressed ( ) . as_slice ( ) )
1539
1497
. expect ( "FATAL: could not convert from StacksPublicKey to PublicKey" ) ;
@@ -1545,13 +1503,11 @@ impl Signer {
1545
1503
return Ok ( ( ) ) ;
1546
1504
}
1547
1505
debug ! (
1548
- "{self}: Received {} block proposals and {} messages from the miner" ,
1549
- blocks. len( ) ,
1506
+ "{self}: Received {} messages from the miner" ,
1550
1507
messages. len( ) ;
1551
1508
"miner_key" => ?miner_key,
1552
1509
) ;
1553
1510
self . handle_signer_messages ( stacks_client, res, messages, current_reward_cycle) ;
1554
- self . handle_proposed_blocks ( stacks_client, blocks) ;
1555
1511
}
1556
1512
Some ( SignerEvent :: StatusCheck ) => {
1557
1513
debug ! ( "{self}: Received a status check event." )
0 commit comments