Skip to content

Commit

Permalink
Merge pull request #5466 from stacks-network/chore/add-timestamp-to-b…
Browse files Browse the repository at this point in the history
…lock-response

Add tenure_extend_timestamp to Block Response Accept messages
  • Loading branch information
aldur authored Nov 18, 2024
2 parents bac1b07 + 9b4b89c commit a8c09a1
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 10 deletions.
54 changes: 47 additions & 7 deletions libsigner/src/v0/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,11 +638,16 @@ impl std::fmt::Display for BlockResponse {

impl BlockResponse {
/// Create a new accepted BlockResponse for the provided block signer signature hash and signature
pub fn accepted(hash: Sha512Trunc256Sum, sig: MessageSignature) -> Self {
pub fn accepted(
signer_signature_hash: Sha512Trunc256Sum,
signature: MessageSignature,
tenure_extend_timestamp: u64,
) -> Self {
Self::Accepted(BlockAccepted {
signer_signature_hash: hash,
signature: sig,
signer_signature_hash,
signature,
metadata: SignerMessageMetadata::default(),
tenure_extend_timestamp,
})
}

Expand All @@ -652,8 +657,15 @@ impl BlockResponse {
reject_code: RejectCode,
private_key: &StacksPrivateKey,
mainnet: bool,
timestamp: u64,
) -> Self {
Self::Rejected(BlockRejection::new(hash, reject_code, private_key, mainnet))
Self::Rejected(BlockRejection::new(
hash,
reject_code,
private_key,
mainnet,
timestamp,
))
}
}

Expand Down Expand Up @@ -748,35 +760,45 @@ pub struct BlockAccepted {
pub signature: MessageSignature,
/// Signer message metadata
pub metadata: SignerMessageMetadata,
/// The timestamp at which a tenure extend will be accepted by the responding signer
pub tenure_extend_timestamp: u64,
}

impl StacksMessageCodec for BlockAccepted {
fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), CodecError> {
write_next(fd, &self.signer_signature_hash)?;
write_next(fd, &self.signature)?;
write_next(fd, &self.metadata)?;
write_next(fd, &self.tenure_extend_timestamp)?;
Ok(())
}

fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<Self, CodecError> {
let signer_signature_hash = read_next::<Sha512Trunc256Sum, _>(fd)?;
let signature = read_next::<MessageSignature, _>(fd)?;
let metadata = read_next::<SignerMessageMetadata, _>(fd)?;
let tenure_extend_timestamp = read_next::<u64, _>(fd).unwrap_or(u64::MAX);
Ok(Self {
signer_signature_hash,
signature,
metadata,
tenure_extend_timestamp,
})
}
}

impl BlockAccepted {
/// Create a new BlockAccepted for the provided block signer signature hash and signature
pub fn new(signer_signature_hash: Sha512Trunc256Sum, signature: MessageSignature) -> Self {
pub fn new(
signer_signature_hash: Sha512Trunc256Sum,
signature: MessageSignature,
tenure_extend_timestamp: u64,
) -> Self {
Self {
signer_signature_hash,
signature,
metadata: SignerMessageMetadata::default(),
tenure_extend_timestamp,
}
}
}
Expand All @@ -796,6 +818,8 @@ pub struct BlockRejection {
pub chain_id: u32,
/// Signer message metadata
pub metadata: SignerMessageMetadata,
/// The timestamp at which a tenure extend will be accepted by the responding signer
pub tenure_extend_timestamp: u64,
}

impl BlockRejection {
Expand All @@ -805,6 +829,7 @@ impl BlockRejection {
reason_code: RejectCode,
private_key: &StacksPrivateKey,
mainnet: bool,
timestamp: u64,
) -> Self {
let chain_id = if mainnet {
CHAIN_ID_MAINNET
Expand All @@ -818,6 +843,7 @@ impl BlockRejection {
signature: MessageSignature::empty(),
chain_id,
metadata: SignerMessageMetadata::default(),
tenure_extend_timestamp: timestamp,
};
rejection
.sign(private_key)
Expand All @@ -830,6 +856,7 @@ impl BlockRejection {
reject: BlockValidateReject,
private_key: &StacksPrivateKey,
mainnet: bool,
timestamp: u64,
) -> Self {
let chain_id = if mainnet {
CHAIN_ID_MAINNET
Expand All @@ -843,6 +870,7 @@ impl BlockRejection {
chain_id,
signature: MessageSignature::empty(),
metadata: SignerMessageMetadata::default(),
tenure_extend_timestamp: timestamp,
};
rejection
.sign(private_key)
Expand Down Expand Up @@ -893,6 +921,7 @@ impl StacksMessageCodec for BlockRejection {
write_next(fd, &self.chain_id)?;
write_next(fd, &self.signature)?;
write_next(fd, &self.metadata)?;
write_next(fd, &self.tenure_extend_timestamp)?;
Ok(())
}

Expand All @@ -906,13 +935,15 @@ impl StacksMessageCodec for BlockRejection {
let chain_id = read_next::<u32, _>(fd)?;
let signature = read_next::<MessageSignature, _>(fd)?;
let metadata = read_next::<SignerMessageMetadata, _>(fd)?;
let tenure_extend_timestamp = read_next::<u64, _>(fd).unwrap_or(u64::MAX);
Ok(Self {
reason,
reason_code,
signer_signature_hash,
chain_id,
signature,
metadata,
tenure_extend_timestamp,
})
}
}
Expand Down Expand Up @@ -1046,6 +1077,7 @@ mod test {
RejectCode::ValidationFailed(ValidateRejectCode::InvalidBlock),
&StacksPrivateKey::new(),
thread_rng().gen_bool(0.5),
thread_rng().next_u64(),
);
let serialized_rejection = rejection.serialize_to_vec();
let deserialized_rejection = read_next::<BlockRejection, _>(&mut &serialized_rejection[..])
Expand All @@ -1057,6 +1089,7 @@ mod test {
RejectCode::ConnectivityIssues,
&StacksPrivateKey::new(),
thread_rng().gen_bool(0.5),
thread_rng().next_u64(),
);
let serialized_rejection = rejection.serialize_to_vec();
let deserialized_rejection = read_next::<BlockRejection, _>(&mut &serialized_rejection[..])
Expand All @@ -1070,6 +1103,7 @@ mod test {
signer_signature_hash: Sha512Trunc256Sum([0u8; 32]),
signature: MessageSignature::empty(),
metadata: SignerMessageMetadata::default(),
tenure_extend_timestamp: thread_rng().next_u64(),
};
let response = BlockResponse::Accepted(accepted);
let serialized_response = response.serialize_to_vec();
Expand All @@ -1082,6 +1116,7 @@ mod test {
RejectCode::ValidationFailed(ValidateRejectCode::InvalidBlock),
&StacksPrivateKey::new(),
thread_rng().gen_bool(0.5),
thread_rng().next_u64(),
));
let serialized_response = response.serialize_to_vec();
let deserialized_response = read_next::<BlockResponse, _>(&mut &serialized_response[..])
Expand All @@ -1095,6 +1130,7 @@ mod test {
signer_signature_hash: Sha512Trunc256Sum([2u8; 32]),
signature: MessageSignature::empty(),
metadata: SignerMessageMetadata::default(),
tenure_extend_timestamp: thread_rng().next_u64(),
};
let signer_message = SignerMessage::BlockResponse(BlockResponse::Accepted(accepted));
let serialized_signer_message = signer_message.serialize_to_vec();
Expand Down Expand Up @@ -1258,6 +1294,7 @@ mod test {
chain_id: CHAIN_ID_TESTNET,
signature: MessageSignature::from_hex("006fb349212e1a1af1a3c712878d5159b5ec14636adb6f70be00a6da4ad4f88a9934d8a9abb229620dd8e0f225d63401e36c64817fb29e6c05591dcbe95c512df3").unwrap(),
metadata: SignerMessageMetadata::empty(),
tenure_extend_timestamp: u64::MAX
}))
);

Expand All @@ -1270,15 +1307,16 @@ mod test {
.unwrap(),
metadata: SignerMessageMetadata::empty(),
signature: MessageSignature::from_hex("001c694f8134c5c90f2f2bcd330e9f423204884f001b5df0050f36a2c4ff79dd93522bb2ae395ea87de4964886447507c18374b7a46ee2e371e9bf332f0706a3e8").unwrap(),
tenure_extend_timestamp: u64::MAX
}))
);
}

#[test]
fn test_block_response_metadata() {
let block_rejected_hex = "010100000050426c6f636b206973206e6f7420612074656e7572652d737461727420626c6f636b2c20616e642068617320616e20756e7265636f676e697a65642074656e75726520636f6e73656e7375732068617368000691f95f84b7045f7dce7757052caa986ef042cb58f7df5031a3b5b5d0e3dda63e80000000006fb349212e1a1af1a3c712878d5159b5ec14636adb6f70be00a6da4ad4f88a9934d8a9abb229620dd8e0f225d63401e36c64817fb29e6c05591dcbe95c512df30000000b48656c6c6f20776f726c64";
let block_rejected_hex = "010100000050426c6f636b206973206e6f7420612074656e7572652d737461727420626c6f636b2c20616e642068617320616e20756e7265636f676e697a65642074656e75726520636f6e73656e7375732068617368000691f95f84b7045f7dce7757052caa986ef042cb58f7df5031a3b5b5d0e3dda63e80000000006fb349212e1a1af1a3c712878d5159b5ec14636adb6f70be00a6da4ad4f88a9934d8a9abb229620dd8e0f225d63401e36c64817fb29e6c05591dcbe95c512df30000000b48656c6c6f20776f726c6400";
let block_rejected_bytes = hex_bytes(&block_rejected_hex).unwrap();
let block_accepted_hex = "010011717149677c2ac97d15ae5954f7a716f10100b9cb81a2bf27551b2f2e54ef19001c694f8134c5c90f2f2bcd330e9f423204884f001b5df0050f36a2c4ff79dd93522bb2ae395ea87de4964886447507c18374b7a46ee2e371e9bf332f0706a3e80000000b48656c6c6f20776f726c64";
let block_accepted_hex = "010011717149677c2ac97d15ae5954f7a716f10100b9cb81a2bf27551b2f2e54ef19001c694f8134c5c90f2f2bcd330e9f423204884f001b5df0050f36a2c4ff79dd93522bb2ae395ea87de4964886447507c18374b7a46ee2e371e9bf332f0706a3e80000000b48656c6c6f20776f726c6400";
let block_accepted_bytes = hex_bytes(&block_accepted_hex).unwrap();
let block_rejected = read_next::<SignerMessage, _>(&mut &block_rejected_bytes[..])
.expect("Failed to deserialize BlockRejection");
Expand All @@ -1296,6 +1334,7 @@ mod test {
metadata: SignerMessageMetadata {
server_version: "Hello world".to_string(),
},
tenure_extend_timestamp: u64::MAX,
}))
);

Expand All @@ -1310,6 +1349,7 @@ mod test {
server_version: "Hello world".to_string(),
},
signature: MessageSignature::from_hex("001c694f8134c5c90f2f2bcd330e9f423204884f001b5df0050f36a2c4ff79dd93522bb2ae395ea87de4964886447507c18374b7a46ee2e371e9bf332f0706a3e8").unwrap(),
tenure_extend_timestamp: u64::MAX
}))
);
}
Expand Down
2 changes: 2 additions & 0 deletions stacks-signer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and this project adheres to the versioning scheme outlined in the [README.md](RE

### Changed

- Add tenure extend timestamp to signer block responses

## [3.0.0.0.1.0]

### Changed
Expand Down
1 change: 1 addition & 0 deletions stacks-signer/src/client/stackerdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ mod tests {
chain_id: thread_rng().next_u32(),
signature: MessageSignature::empty(),
metadata: SignerMessageMetadata::empty(),
tenure_extend_timestamp: thread_rng().next_u64(),
};
let signer_message = SignerMessage::BlockResponse(BlockResponse::Rejected(block_reject));
let ack = StackerDBChunkAckData {
Expand Down
2 changes: 1 addition & 1 deletion stacks-signer/src/tests/conf/signer-0.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
stacks_private_key = "6a1fc1a3183018c6d79a4e11e154d2bdad2d89ac8bc1b0a021de8b4d28774fbb01"
node_host = "127.0.0.1:20443"
endpoint = "localhost:30000"
endpoint = "[::1]:30000"
network = "testnet"
auth_password = "12345"
db_path = ":memory:"
Expand Down
26 changes: 24 additions & 2 deletions stacks-signer/src/v0/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,14 +299,19 @@ impl Signer {
.private_key
.sign(block_info.signer_signature_hash().bits())
.expect("Failed to sign block");
BlockResponse::accepted(block_info.signer_signature_hash(), signature)
BlockResponse::accepted(
block_info.signer_signature_hash(),
signature,
self.calculate_tenure_extend_timestamp(),
)
} else {
debug!("{self}: Rejecting block {}", block_info.block.block_id());
BlockResponse::rejected(
block_info.signer_signature_hash(),
RejectCode::RejectedInPriorRound,
&self.private_key,
self.mainnet,
self.calculate_tenure_extend_timestamp(),
)
};
Some(response)
Expand Down Expand Up @@ -409,6 +414,7 @@ impl Signer {
RejectCode::ConnectivityIssues,
&self.private_key,
self.mainnet,
self.calculate_tenure_extend_timestamp(),
))
}
// Block proposal is bad
Expand All @@ -423,6 +429,7 @@ impl Signer {
RejectCode::SortitionViewMismatch,
&self.private_key,
self.mainnet,
self.calculate_tenure_extend_timestamp(),
))
}
// Block proposal passed check, still don't know if valid
Expand All @@ -439,6 +446,7 @@ impl Signer {
RejectCode::NoSortitionView,
&self.private_key,
self.mainnet,
self.calculate_tenure_extend_timestamp(),
))
};

Expand Down Expand Up @@ -569,7 +577,11 @@ impl Signer {
self.signer_db
.insert_block(&block_info)
.unwrap_or_else(|_| panic!("{self}: Failed to insert block in DB"));
let accepted = BlockAccepted::new(block_info.signer_signature_hash(), signature);
let accepted = BlockAccepted::new(
block_info.signer_signature_hash(),
signature,
self.calculate_tenure_extend_timestamp(),
);
// have to save the signature _after_ the block info
self.handle_block_signature(stacks_client, &accepted);
Some(BlockResponse::Accepted(accepted))
Expand Down Expand Up @@ -623,6 +635,7 @@ impl Signer {
block_validate_reject.clone(),
&self.private_key,
self.mainnet,
self.calculate_tenure_extend_timestamp(),
);
self.signer_db
.insert_block(&block_info)
Expand Down Expand Up @@ -720,6 +733,7 @@ impl Signer {
RejectCode::ConnectivityIssues,
&self.private_key,
self.mainnet,
self.calculate_tenure_extend_timestamp(),
);
if let Err(e) = block_info.mark_locally_rejected() {
warn!("{self}: Failed to mark block as locally rejected: {e:?}",);
Expand Down Expand Up @@ -865,6 +879,7 @@ impl Signer {
signer_signature_hash: block_hash,
signature,
metadata,
..
} = accepted;
debug!(
"{self}: Received a block-accept signature: ({block_hash}, {signature}, {})",
Expand Down Expand Up @@ -1101,6 +1116,7 @@ impl Signer {
RejectCode::TestingDirective,
&self.private_key,
self.mainnet,
self.calculate_tenure_extend_timestamp(),
))
} else {
None
Expand All @@ -1119,4 +1135,10 @@ impl Signer {
warn!("{self}: Failed to send mock signature to stacker-db: {e:?}",);
}
}

/// Calculate the tenure extend timestamp based on the tenure start and already consumed idle time
fn calculate_tenure_extend_timestamp(&self) -> u64 {
// TODO: udpate this to grab the idle time consumed against the tenure start time
get_epoch_time_secs()
}
}
1 change: 1 addition & 0 deletions testnet/stacks-node/src/nakamoto_node/sign_coordinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ impl SignCoordinator {
signer_signature_hash: response_hash,
signature,
metadata,
tenure_extend_timestamp: _, // TOOD: utilize this info
} = accepted;
let block_sighash = block.header.signer_signature_hash();
if block_sighash != response_hash {
Expand Down

0 comments on commit a8c09a1

Please sign in to comment.