Skip to content

Commit fdbecce

Browse files
committed
feat: add new signer reject codes
These codes provide more insight into why a signer rejected a block and will be used for implementing the changes in #5820.
1 parent fd416d4 commit fdbecce

File tree

6 files changed

+238
-126
lines changed

6 files changed

+238
-126
lines changed

libsigner/src/v0/messages.rs

Lines changed: 124 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,28 @@ RejectCodeTypePrefix {
539539
/// The block was rejected due to a mismatch with expected sortition view
540540
SortitionViewMismatch = 4,
541541
/// The block was rejected due to a testing directive
542-
TestingDirective = 5
542+
TestingDirective = 5,
543+
/// The block attempted to reorg the previous tenure but was not allowed
544+
ReorgNotAllowed = 6,
545+
/// The bitvec field does not match what is expected
546+
InvalidBitvec = 7,
547+
/// The miner's pubkey hash does not match the winning pubkey hash
548+
PubkeyHashMismatch = 8,
549+
/// The miner has been marked as invalid
550+
InvalidMiner = 9,
551+
/// Miner is last sortition winner, when the current sortition winner is
552+
/// still valid
553+
NotLatestSortitionWinner = 10,
554+
/// The block does not confirm the expected parent block
555+
InvalidParentBlock = 11,
556+
/// The block does not confirm the expected parent tenure
557+
InvalidParentTenure = 12,
558+
/// The block contains a block found tenure change, but we've already seen
559+
/// a block found
560+
DuplicateBlockFound = 13,
561+
/// The block attempted a tenure extend but the burn view has not changed
562+
/// and not enough time has passed for a time-based tenure extend
563+
InvalidTenureExtend = 14
543564
});
544565

545566
impl TryFrom<u8> for RejectCodeTypePrefix {
@@ -555,11 +576,20 @@ impl From<&RejectCode> for RejectCodeTypePrefix {
555576
fn from(reject_code: &RejectCode) -> Self {
556577
match reject_code {
557578
RejectCode::ValidationFailed(_) => RejectCodeTypePrefix::ValidationFailed,
558-
RejectCode::ConnectivityIssues => RejectCodeTypePrefix::ConnectivityIssues,
579+
RejectCode::ConnectivityIssues(_) => RejectCodeTypePrefix::ConnectivityIssues,
559580
RejectCode::RejectedInPriorRound => RejectCodeTypePrefix::RejectedInPriorRound,
560581
RejectCode::NoSortitionView => RejectCodeTypePrefix::NoSortitionView,
561582
RejectCode::SortitionViewMismatch => RejectCodeTypePrefix::SortitionViewMismatch,
562583
RejectCode::TestingDirective => RejectCodeTypePrefix::TestingDirective,
584+
RejectCode::ReorgNotAllowed => RejectCodeTypePrefix::ReorgNotAllowed,
585+
RejectCode::InvalidBitvec => RejectCodeTypePrefix::InvalidBitvec,
586+
RejectCode::PubkeyHashMismatch => RejectCodeTypePrefix::PubkeyHashMismatch,
587+
RejectCode::InvalidMiner => RejectCodeTypePrefix::InvalidMiner,
588+
RejectCode::NotLatestSortitionWinner => RejectCodeTypePrefix::NotLatestSortitionWinner,
589+
RejectCode::InvalidParentBlock => RejectCodeTypePrefix::InvalidParentBlock,
590+
RejectCode::InvalidParentTenure => RejectCodeTypePrefix::InvalidParentTenure,
591+
RejectCode::DuplicateBlockFound => RejectCodeTypePrefix::DuplicateBlockFound,
592+
RejectCode::InvalidTenureExtend => RejectCodeTypePrefix::InvalidTenureExtend,
563593
}
564594
}
565595
}
@@ -572,13 +602,34 @@ pub enum RejectCode {
572602
/// No Sortition View to verify against
573603
NoSortitionView,
574604
/// The block was rejected due to connectivity issues with the signer
575-
ConnectivityIssues,
605+
ConnectivityIssues(String),
576606
/// The block was rejected in a prior round
577607
RejectedInPriorRound,
578608
/// The block was rejected due to a mismatch with expected sortition view
579609
SortitionViewMismatch,
580610
/// The block was rejected due to a testing directive
581611
TestingDirective,
612+
/// The block attempted to reorg the previous tenure but was not allowed
613+
ReorgNotAllowed,
614+
/// The bitvec field does not match what is expected
615+
InvalidBitvec,
616+
/// The miner's pubkey hash does not match the winning pubkey hash
617+
PubkeyHashMismatch,
618+
/// The miner has been marked as invalid
619+
InvalidMiner,
620+
/// Miner is last sortition winner, when the current sortition winner is
621+
/// still valid
622+
NotLatestSortitionWinner,
623+
/// The block does not confirm the expected parent block
624+
InvalidParentBlock,
625+
/// The block does not confirm the expected parent tenure
626+
InvalidParentTenure,
627+
/// The block contains a block found tenure change, but we've already seen
628+
/// a block found
629+
DuplicateBlockFound,
630+
/// The block attempted a tenure extend but the burn view has not changed
631+
/// and not enough time has passed for a time-based tenure extend
632+
InvalidTenureExtend,
582633
}
583634

584635
define_u8_enum!(
@@ -796,7 +847,7 @@ impl SignerMessageMetadata {
796847
}
797848

798849
/// The latest version of the block response data
799-
pub const BLOCK_RESPONSE_DATA_VERSION: u8 = 2;
850+
pub const BLOCK_RESPONSE_DATA_VERSION: u8 = 3;
800851

801852
/// Versioned, backwards-compatible struct for block response data
802853
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@@ -1070,11 +1121,20 @@ impl StacksMessageCodec for RejectCode {
10701121
// Do not do a single match here as we may add other variants in the future and don't want to miss adding it
10711122
match self {
10721123
RejectCode::ValidationFailed(code) => write_next(fd, &(*code as u8))?,
1073-
RejectCode::ConnectivityIssues
1124+
RejectCode::ConnectivityIssues(_)
10741125
| RejectCode::RejectedInPriorRound
10751126
| RejectCode::NoSortitionView
10761127
| RejectCode::SortitionViewMismatch
1077-
| RejectCode::TestingDirective => {
1128+
| RejectCode::TestingDirective
1129+
| RejectCode::ReorgNotAllowed
1130+
| RejectCode::InvalidBitvec
1131+
| RejectCode::PubkeyHashMismatch
1132+
| RejectCode::InvalidMiner
1133+
| RejectCode::NotLatestSortitionWinner
1134+
| RejectCode::InvalidParentBlock
1135+
| RejectCode::InvalidParentTenure
1136+
| RejectCode::DuplicateBlockFound
1137+
| RejectCode::InvalidTenureExtend => {
10781138
// No additional data to serialize / deserialize
10791139
}
10801140
};
@@ -1093,11 +1153,22 @@ impl StacksMessageCodec for RejectCode {
10931153
))
10941154
})?,
10951155
),
1096-
RejectCodeTypePrefix::ConnectivityIssues => RejectCode::ConnectivityIssues,
1156+
RejectCodeTypePrefix::ConnectivityIssues => {
1157+
RejectCode::ConnectivityIssues("unspecified".to_string())
1158+
}
10971159
RejectCodeTypePrefix::RejectedInPriorRound => RejectCode::RejectedInPriorRound,
10981160
RejectCodeTypePrefix::NoSortitionView => RejectCode::NoSortitionView,
10991161
RejectCodeTypePrefix::SortitionViewMismatch => RejectCode::SortitionViewMismatch,
11001162
RejectCodeTypePrefix::TestingDirective => RejectCode::TestingDirective,
1163+
RejectCodeTypePrefix::ReorgNotAllowed => RejectCode::ReorgNotAllowed,
1164+
RejectCodeTypePrefix::InvalidBitvec => RejectCode::InvalidBitvec,
1165+
RejectCodeTypePrefix::PubkeyHashMismatch => RejectCode::PubkeyHashMismatch,
1166+
RejectCodeTypePrefix::InvalidMiner => RejectCode::InvalidMiner,
1167+
RejectCodeTypePrefix::NotLatestSortitionWinner => RejectCode::NotLatestSortitionWinner,
1168+
RejectCodeTypePrefix::InvalidParentBlock => RejectCode::InvalidParentBlock,
1169+
RejectCodeTypePrefix::InvalidParentTenure => RejectCode::InvalidParentTenure,
1170+
RejectCodeTypePrefix::DuplicateBlockFound => RejectCode::DuplicateBlockFound,
1171+
RejectCodeTypePrefix::InvalidTenureExtend => RejectCode::InvalidTenureExtend,
11011172
};
11021173
Ok(code)
11031174
}
@@ -1108,9 +1179,9 @@ impl std::fmt::Display for RejectCode {
11081179
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
11091180
match self {
11101181
RejectCode::ValidationFailed(code) => write!(f, "Validation failed: {:?}", code),
1111-
RejectCode::ConnectivityIssues => write!(
1182+
RejectCode::ConnectivityIssues(reason) => write!(
11121183
f,
1113-
"The block was rejected due to connectivity issues with the signer."
1184+
"The block was rejected due to connectivity issues with the signer: {reason}"
11141185
),
11151186
RejectCode::RejectedInPriorRound => write!(
11161187
f,
@@ -1128,6 +1199,48 @@ impl std::fmt::Display for RejectCode {
11281199
RejectCode::TestingDirective => {
11291200
write!(f, "The block was rejected due to a testing directive.")
11301201
}
1202+
RejectCode::ReorgNotAllowed => {
1203+
write!(
1204+
f,
1205+
"The block attempted to reorg the previous tenure but was not allowed."
1206+
)
1207+
}
1208+
RejectCode::InvalidBitvec => {
1209+
write!(f, "The bitvec field does not match what is expected.")
1210+
}
1211+
RejectCode::PubkeyHashMismatch => {
1212+
write!(
1213+
f,
1214+
"The miner's pubkey hash does not match the winning pubkey hash."
1215+
)
1216+
}
1217+
RejectCode::InvalidMiner => {
1218+
write!(f, "The miner has been marked as invalid.")
1219+
}
1220+
RejectCode::NotLatestSortitionWinner => {
1221+
write!(
1222+
f,
1223+
"Miner is last sortition winner, when the current sortition winner is still valid."
1224+
)
1225+
}
1226+
RejectCode::InvalidParentBlock => {
1227+
write!(f, "The block does not confirm the expected parent block.")
1228+
}
1229+
RejectCode::InvalidParentTenure => {
1230+
write!(f, "The block does not confirm the expected parent tenure.")
1231+
}
1232+
RejectCode::DuplicateBlockFound => {
1233+
write!(
1234+
f,
1235+
"The block contains a block found tenure change, but we've already seen a block found."
1236+
)
1237+
}
1238+
RejectCode::InvalidTenureExtend => {
1239+
write!(
1240+
f,
1241+
"The block attempted a tenure extend but the burn view has not changed and not enough time has passed for a time-based tenure extend."
1242+
)
1243+
}
11311244
}
11321245
}
11331246
}
@@ -1180,7 +1293,7 @@ mod test {
11801293
.expect("Failed to deserialize RejectCode");
11811294
assert_eq!(code, deserialized_code);
11821295

1183-
let code = RejectCode::ConnectivityIssues;
1296+
let code = RejectCode::ConnectivityIssues("".to_string());
11841297
let serialized_code = code.serialize_to_vec();
11851298
let deserialized_code = read_next::<RejectCode, _>(&mut &serialized_code[..])
11861299
.expect("Failed to deserialize RejectCode");
@@ -1203,7 +1316,7 @@ mod test {
12031316

12041317
let rejection = BlockRejection::new(
12051318
Sha512Trunc256Sum([1u8; 32]),
1206-
RejectCode::ConnectivityIssues,
1319+
RejectCode::ConnectivityIssues("reason".to_string()),
12071320
&StacksPrivateKey::random(),
12081321
thread_rng().gen_bool(0.5),
12091322
thread_rng().next_u64(),

stacks-signer/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE
1616
- Increase default `block_proposal_timeout_ms` from 10 minutes to 4 hours. Until #5729 is implemented, there is no value in rejecting a late block from a miner, since a late block is better than no block at all.
1717
- Signers no longer view any block proposal by a miner in their DB as indicative of valid miner activity.
1818
- Various index improvements to the signer's database to improve performance.
19+
- Add new reject codes to the signer response for better visibility into why a block was rejected.
1920

2021
## [3.1.0.0.5.0]
2122

0 commit comments

Comments
 (0)