@@ -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
@@ -439,31 +445,31 @@ impl Signer {
439
445
self . update_operation ( Operation :: Dkg ) ;
440
446
}
441
447
Command :: Sign {
442
- block ,
448
+ block_proposal ,
443
449
is_taproot,
444
450
merkle_root,
445
451
} => {
446
452
if self . approved_aggregate_public_key . is_none ( ) {
447
453
debug ! ( "{self}: Cannot sign a block without an approved aggregate public key. Ignore it." ) ;
448
454
return ;
449
455
}
450
- let signer_signature_hash = block. header . signer_signature_hash ( ) ;
456
+ let signer_signature_hash = block_proposal . block . header . signer_signature_hash ( ) ;
451
457
let mut block_info = self
452
458
. signer_db
453
459
. block_lookup ( self . reward_cycle , & signer_signature_hash)
454
- . unwrap_or_else ( |_| Some ( BlockInfo :: new ( block . clone ( ) ) ) )
455
- . unwrap_or_else ( || BlockInfo :: new ( block . clone ( ) ) ) ;
460
+ . unwrap_or_else ( |_| Some ( BlockInfo :: from ( block_proposal . clone ( ) ) ) )
461
+ . unwrap_or_else ( || BlockInfo :: from ( block_proposal . clone ( ) ) ) ;
456
462
if block_info. signed_over {
457
463
debug ! ( "{self}: Received a sign command for a block we are already signing over. Ignore it." ) ;
458
464
return ;
459
465
}
460
466
info ! ( "{self}: Signing block" ;
461
- "block_consensus_hash" => %block. header. consensus_hash,
462
- "block_height" => block. header. chain_length,
463
- "pre_sign_block_id" => %block. block_id( ) ,
467
+ "block_consensus_hash" => %block_proposal . block. header. consensus_hash,
468
+ "block_height" => block_proposal . block. header. chain_length,
469
+ "pre_sign_block_id" => %block_proposal . block. block_id( ) ,
464
470
) ;
465
471
match self . coordinator . start_signing_round (
466
- & block . serialize_to_vec ( ) ,
472
+ & block_proposal . serialize_to_vec ( ) ,
467
473
* is_taproot,
468
474
* merkle_root,
469
475
) {
@@ -472,7 +478,7 @@ impl Signer {
472
478
debug ! ( "{self}: ACK: {ack:?}" , ) ;
473
479
block_info. signed_over = true ;
474
480
self . signer_db
475
- . insert_block ( self . reward_cycle , & block_info)
481
+ . insert_block ( & block_info)
476
482
. unwrap_or_else ( |e| {
477
483
error ! ( "{self}: Failed to insert block in DB: {e:?}" ) ;
478
484
} ) ;
@@ -562,7 +568,7 @@ impl Signer {
562
568
let is_valid = self . verify_block_transactions ( stacks_client, & block_info. block ) ;
563
569
block_info. valid = Some ( is_valid) ;
564
570
self . signer_db
565
- . insert_block ( self . reward_cycle , & block_info)
571
+ . insert_block ( & block_info)
566
572
. unwrap_or_else ( |_| panic ! ( "{self}: Failed to insert block in DB" ) ) ;
567
573
info ! (
568
574
"{self}: Treating block validation for block {} as valid: {:?}" ,
@@ -619,7 +625,7 @@ impl Signer {
619
625
"signed_over" => block_info. signed_over,
620
626
) ;
621
627
self . signer_db
622
- . insert_block ( self . reward_cycle , & block_info)
628
+ . insert_block ( & block_info)
623
629
. unwrap_or_else ( |_| panic ! ( "{self}: Failed to insert block in DB" ) ) ;
624
630
}
625
631
@@ -652,63 +658,6 @@ impl Signer {
652
658
self . handle_packets ( stacks_client, res, & packets, current_reward_cycle) ;
653
659
}
654
660
655
- /// Handle proposed blocks submitted by the miners to stackerdb
656
- fn handle_proposed_blocks (
657
- & mut self ,
658
- stacks_client : & StacksClient ,
659
- proposals : & [ BlockProposalSigners ] ,
660
- ) {
661
- for proposal in proposals {
662
- if proposal. reward_cycle != self . reward_cycle {
663
- debug ! (
664
- "{self}: Received proposal for block outside of my reward cycle, ignoring." ;
665
- "proposal_reward_cycle" => proposal. reward_cycle,
666
- "proposal_burn_height" => proposal. burn_height,
667
- ) ;
668
- continue ;
669
- }
670
- let sig_hash = proposal. block . header . signer_signature_hash ( ) ;
671
- match self . signer_db . block_lookup ( self . reward_cycle , & sig_hash) {
672
- Ok ( Some ( block) ) => {
673
- debug ! (
674
- "{self}: Received proposal for block already known, ignoring new proposal." ;
675
- "signer_sighash" => %sig_hash,
676
- "proposal_burn_height" => proposal. burn_height,
677
- "vote" => ?block. vote. as_ref( ) . map( |v| {
678
- if v. rejected {
679
- "REJECT"
680
- } else {
681
- "ACCEPT"
682
- }
683
- } ) ,
684
- "signed_over" => block. signed_over,
685
- ) ;
686
- continue ;
687
- }
688
- Ok ( None ) => {
689
- // Store the block in our cache
690
- self . signer_db
691
- . insert_block ( self . reward_cycle , & BlockInfo :: new ( proposal. block . clone ( ) ) )
692
- . unwrap_or_else ( |e| {
693
- error ! ( "{self}: Failed to insert block in DB: {e:?}" ) ;
694
- } ) ;
695
- // Submit the block for validation
696
- stacks_client
697
- . submit_block_for_validation ( proposal. block . clone ( ) )
698
- . unwrap_or_else ( |e| {
699
- warn ! ( "{self}: Failed to submit block for validation: {e:?}" ) ;
700
- } ) ;
701
- }
702
- Err ( e) => {
703
- error ! (
704
- "{self}: Failed to lookup block in DB: {e:?}. Dropping proposal request."
705
- ) ;
706
- continue ;
707
- }
708
- }
709
- }
710
- }
711
-
712
661
/// Helper function for determining if the provided message is a DKG specific message
713
662
fn is_dkg_message ( msg : & Message ) -> bool {
714
663
matches ! (
@@ -853,26 +802,35 @@ impl Signer {
853
802
stacks_client : & StacksClient ,
854
803
nonce_request : & mut NonceRequest ,
855
804
) -> Option < BlockInfo > {
856
- let Some ( block ) =
857
- NakamotoBlock :: consensus_deserialize ( & mut nonce_request. message . as_slice ( ) ) . ok ( )
805
+ let Some ( block_proposal ) =
806
+ BlockProposalSigners :: consensus_deserialize ( & mut nonce_request. message . as_slice ( ) ) . ok ( )
858
807
else {
859
- // We currently reject anything that is not a block
808
+ // We currently reject anything that is not a valid block proposal
860
809
warn ! ( "{self}: Received a nonce request for an unknown message stream. Reject it." , ) ;
861
810
return None ;
862
811
} ;
863
- let signer_signature_hash = block. header . signer_signature_hash ( ) ;
812
+ if block_proposal. reward_cycle != self . reward_cycle {
813
+ // We are not signing for this reward cycle. Reject the block
814
+ warn ! (
815
+ "{self}: Received a nonce request for a different reward cycle. Reject it." ;
816
+ "requested_reward_cycle" => block_proposal. reward_cycle,
817
+ ) ;
818
+ return None ;
819
+ }
820
+ // 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.
821
+ let signer_signature_hash = block_proposal. block . header . signer_signature_hash ( ) ;
864
822
let Some ( mut block_info) = self
865
823
. signer_db
866
824
. block_lookup ( self . reward_cycle , & signer_signature_hash)
867
825
. expect ( "Failed to connect to signer DB" )
868
826
else {
869
827
debug ! (
870
- "{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... " ;
871
- "signer_sighash" => %block . header . signer_signature_hash( ) ,
828
+ "{self}: received a nonce request for a new block. Submit block for validation. " ;
829
+ "signer_sighash" => %signer_signature_hash,
872
830
) ;
873
- let block_info = BlockInfo :: new_with_request ( block . clone ( ) , nonce_request. clone ( ) ) ;
831
+ let block_info = BlockInfo :: new_with_request ( block_proposal , nonce_request. clone ( ) ) ;
874
832
stacks_client
875
- . submit_block_for_validation ( block)
833
+ . submit_block_for_validation ( block_info . block . clone ( ) )
876
834
. unwrap_or_else ( |e| {
877
835
warn ! ( "{self}: Failed to submit block for validation: {e:?}" , ) ;
878
836
} ) ;
@@ -1045,7 +1003,7 @@ impl Signer {
1045
1003
return None ;
1046
1004
} ;
1047
1005
self . signer_db
1048
- . insert_block ( self . reward_cycle , & updated_block_info)
1006
+ . insert_block ( & updated_block_info)
1049
1007
. unwrap_or_else ( |_| panic ! ( "{self}: Failed to insert block in DB" ) ) ;
1050
1008
let process_request = updated_block_info. vote . is_some ( ) ;
1051
1009
if !process_request {
@@ -1614,7 +1572,7 @@ impl Signer {
1614
1572
) ;
1615
1573
self . handle_signer_messages ( stacks_client, res, messages, current_reward_cycle) ;
1616
1574
}
1617
- Some ( SignerEvent :: MinerMessages ( blocks , messages, miner_key) ) => {
1575
+ Some ( SignerEvent :: MinerMessages ( messages, miner_key) ) => {
1618
1576
if let Some ( miner_key) = miner_key {
1619
1577
let miner_key = PublicKey :: try_from ( miner_key. to_bytes_compressed ( ) . as_slice ( ) )
1620
1578
. expect ( "FATAL: could not convert from StacksPublicKey to PublicKey" ) ;
@@ -1626,13 +1584,11 @@ impl Signer {
1626
1584
return Ok ( ( ) ) ;
1627
1585
}
1628
1586
debug ! (
1629
- "{self}: Received {} block proposals and {} messages from the miner" ,
1630
- blocks. len( ) ,
1587
+ "{self}: Received {} messages from the miner" ,
1631
1588
messages. len( ) ;
1632
1589
"miner_key" => ?miner_key,
1633
1590
) ;
1634
1591
self . handle_signer_messages ( stacks_client, res, messages, current_reward_cycle) ;
1635
- self . handle_proposed_blocks ( stacks_client, blocks) ;
1636
1592
}
1637
1593
Some ( SignerEvent :: StatusCheck ) => {
1638
1594
debug ! ( "{self}: Received a status check event." )
0 commit comments