Skip to content

Commit

Permalink
Add TODO for miner public key verification
Browse files Browse the repository at this point in the history
Signed-off-by: Jacinta Ferrant <[email protected]>
  • Loading branch information
jferrant committed Dec 6, 2023
1 parent 4829a40 commit c475d16
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
1 change: 1 addition & 0 deletions stacks-signer/src/client/stackerdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub enum StackerDBMessage {
// TODO: update this to use a struct that lists optional error code if the block is invalid
// to prove that the signers have considered the block but rejected it. This should include
// hints about how to fix the block
// Update to use NakamotoBlockProposal. Depends on https://github.com/stacks-network/stacks-core/pull/4084
Block(NakamotoBlock),
/// DKG and Signing round data for other signers to observe
Packet(Packet),
Expand Down
27 changes: 27 additions & 0 deletions stacks-signer/src/client/stacks_client.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use blockstack_lib::burnchains::Txid;
use blockstack_lib::chainstate::nakamoto::NakamotoBlock;
use blockstack_lib::chainstate::stacks::{
StacksTransaction, StacksTransactionSigner, TransactionAnchorMode, TransactionAuth,
TransactionContractCall, TransactionPayload, TransactionPostConditionMode,
Expand Down Expand Up @@ -50,6 +51,28 @@ impl From<&Config> for StacksClient {
}

impl StacksClient {
/// Retrieve the current miner public key
pub fn get_miner_public_key(&self) -> Result<StacksPublicKey, ClientError> {
// TODO: Depends on https://github.com/stacks-network/stacks-core/issues/4018
todo!("Get the miner public key from the stacks node to verify the miner blocks were signed by the correct miner");
}

/// Check if the proposed Nakamoto block is a valid block
pub fn is_valid_nakamoto_block(&self, _block: &NakamotoBlock) -> Result<bool, ClientError> {
// TODO: Depends on https://github.com/stacks-network/stacks-core/issues/3866
let send_request = || {
self.stacks_node_client
.get(self.block_proposal_path())
.send()
.map_err(backoff::Error::transient)
};
let response = retry_with_exponential_backoff(send_request)?;
if !response.status().is_success() {
return Err(ClientError::RequestFailure(response.status()));
}
todo!("Call the appropriate RPC endpoint to check if the proposed Nakamoto block is valid");
}

/// Retrieve the current DKG aggregate public key
pub fn get_aggregate_public_key(&self) -> Result<Option<Point>, ClientError> {
let reward_cycle = self.get_current_reward_cycle()?;
Expand Down Expand Up @@ -300,6 +323,10 @@ impl StacksClient {
self.http_origin
)
}

fn block_proposal_path(&self) -> String {
format!("{}/v2/block-proposal", self.http_origin)
}
}

#[cfg(test)]
Expand Down
22 changes: 22 additions & 0 deletions stacks-signer/src/runloop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,27 @@ impl<C: Coordinator> RunLoop<C> {
// Received a block proposal from the miner.
// If the signer is the coordinator, then trigger a Signing round for the block
if coordinator_id == self.signing_round.signer_id {
// Don't bother triggering a signing round for the block if it is invalid
if !self.stacks_client.is_valid_nakamoto_block(&block).unwrap_or_else(|e| {
warn!("Failed to validate block: {:?}", e);
false
}) {
warn!("Received an invalid block proposal from the miner. Ignoring block proposal: {:?}", block);
return;
}

// TODO: dependent on https://github.com/stacks-network/stacks-core/issues/4018
// let miner_public_key = self.stacks_client.get_miner_public_key().expect("Failed to get miner public key. Cannot verify blocks.");
// let Some(block_miner_public_key) = block.header.recover_miner_pk() else {
// warn!("Failed to recover miner public key from block. Ignoring block proposal: {:?}", block);
// return;
// };
// if block_miner_public_key != miner_public_key {
// warn!("Received a block proposal signed with an invalid miner public key. Ignoring block proposal: {:?}.", block);
// return;
// }

// This is a block proposal from the miner. Trigger a signing round for it.
self.commands.push_back(RunLoopCommand::Sign {
message: block.serialize_to_vec(),
is_taproot: false,
Expand Down Expand Up @@ -236,6 +257,7 @@ impl<C: Coordinator> RunLoop<C> {
})
.collect();
// First process all messages as a signer
// TODO: deserialize the packet into a block and verify its contents
let mut outbound_messages = self
.signing_round
.process_inbound_messages(&inbound_messages)
Expand Down

0 comments on commit c475d16

Please sign in to comment.