Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reward set calculation and RPC endpoint #4311

Merged
merged 12 commits into from
Feb 6, 2024
Prev Previous commit
Next Next commit
chore: address PR comments
  • Loading branch information
kantai committed Feb 3, 2024
commit 6ded8d7a7e52609970668645be4469de5ab031cd
16 changes: 0 additions & 16 deletions clarity/src/vm/database/clarity_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,22 +619,6 @@ impl<'a> ClarityDatabase<'a> {
.map_err(|e| e.into())
}

/// Set a metadata entry if it hasn't already been set, yielding
/// a runtime error if it was. This should only be called by post-nakamoto
/// contexts.
pub fn try_set_metadata(
&mut self,
contract_identifier: &QualifiedContractIdentifier,
key: &str,
data: &str,
) -> Result<()> {
if self.store.has_metadata_entry(contract_identifier, key) {
Err(Error::Runtime(RuntimeErrorType::MetadataAlreadySet, None))
} else {
Ok(self.store.insert_metadata(contract_identifier, key, data))
}
}

fn insert_metadata<T: ClaritySerializable>(
&mut self,
contract_identifier: &QualifiedContractIdentifier,
Expand Down
4 changes: 3 additions & 1 deletion stackslib/src/chainstate/coordinator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,9 @@ impl<'a, T: BlockEventDispatcher> RewardSetProvider for OnChainRewardSetProvider
//
// Data **cannot** be read from `.signers` in epoch 2.5 because the write occurs
// in the first block of the prepare phase, but the PoX anchor block is *before*
// the prepare phase. Therefore
// the prepare phase. Therefore, we fetch the reward set in the 2.x style, and then
// apply the necessary nakamoto assertions if the reward set is going to be
// active in Nakamoto (i.e., check for signer set existence).

let is_nakamoto_reward_set = match SortitionDB::get_stacks_epoch_by_epoch_id(
sortdb.conn(),
Expand Down
95 changes: 46 additions & 49 deletions stackslib/src/chainstate/nakamoto/coordinator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,26 @@ use crate::util_lib::db::Error as DBError;
#[cfg(test)]
pub mod tests;

macro_rules! err_or_debug {
($debug_bool:expr, $($arg:tt)*) => ({
if $debug_bool {
debug!($($arg)*)
} else {
error!($($arg)*)
}
})
}

macro_rules! inf_or_debug {
($debug_bool:expr, $($arg:tt)*) => ({
if $debug_bool {
debug!($($arg)*)
} else {
info!($($arg)*)
}
})
}

impl<'a, T: BlockEventDispatcher> OnChainRewardSetProvider<'a, T> {
/// Read a reward_set written while updating .signers
/// `debug_log` should be set to true if the reward set loading should
Expand All @@ -70,6 +90,7 @@ impl<'a, T: BlockEventDispatcher> OnChainRewardSetProvider<'a, T> {
let cycle = burnchain
.block_height_to_reward_cycle(cycle_start_burn_height)
.expect("FATAL: no reward cycle for burn height");

// figure out the block ID
let Some(coinbase_height_of_calculation) = chainstate
.eval_boot_code_read_only(
jcnelson marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -81,17 +102,11 @@ impl<'a, T: BlockEventDispatcher> OnChainRewardSetProvider<'a, T> {
.expect_optional()
.map(|x| u64::try_from(x.expect_u128()).expect("FATAL: block height exceeded u64"))
else {
if debug_log {
debug!(
"The reward set was not written to .signers before it was needed by Nakamoto";
"cycle_number" => cycle,
);
} else {
error!(
"The reward set was not written to .signers before it was needed by Nakamoto";
"cycle_number" => cycle,
);
}
err_or_debug!(
debug_log,
"The reward set was not written to .signers before it was needed by Nakamoto";
"cycle_number" => cycle,
);
return Err(Error::PoXAnchorBlockRequired);
};

Expand All @@ -101,11 +116,10 @@ impl<'a, T: BlockEventDispatcher> OnChainRewardSetProvider<'a, T> {
coinbase_height_of_calculation,
)?
else {
if debug_log {
debug!("Failed to find the block in which .signers was written");
} else {
error!("Failed to find the block in which .signers was written");
}
err_or_debug!(
debug_log,
"Failed to find the block in which .signers was written"
);
return Err(Error::PoXAnchorBlockRequired);
};

Expand All @@ -114,18 +128,12 @@ impl<'a, T: BlockEventDispatcher> OnChainRewardSetProvider<'a, T> {
&reward_set_block.index_block_hash(),
)?
else {
if debug_log {
debug!(
"No reward set stored at the block in which .signers was written";
"checked_block" => %reward_set_block.index_block_hash()
);
} else {
error!(
"No reward set stored at the block in which .signers was written";
"checked_block" => %reward_set_block.index_block_hash(),
"coinbase_height_of_calculation" => coinbase_height_of_calculation,
);
}
err_or_debug!(
debug_log,
"No reward set stored at the block in which .signers was written";
"checked_block" => %reward_set_block.index_block_hash(),
"coinbase_height_of_calculation" => coinbase_height_of_calculation,
);
return Err(Error::PoXAnchorBlockRequired);
};

Expand All @@ -134,32 +142,21 @@ impl<'a, T: BlockEventDispatcher> OnChainRewardSetProvider<'a, T> {
// Non participation is fatal.
if reward_set.rewarded_addresses.is_empty() {
// no one is stacking
if debug_log {
debug!("No PoX participation");
} else {
error!("No PoX participation");
}
err_or_debug!(debug_log, "No PoX participation");
return Err(Error::PoXAnchorBlockRequired);
}

if debug_log {
debug!(
"PoX reward set loaded from written block state";
"reward_set_block_id" => %reward_set_block.index_block_hash(),
);
} else {
info!(
"PoX reward set loaded from written block state";
"reward_set_block_id" => %reward_set_block.index_block_hash(),
);
}
inf_or_debug!(
debug_log,
"PoX reward set loaded from written block state";
"reward_set_block_id" => %reward_set_block.index_block_hash(),
);

if reward_set.signers.is_none() {
if debug_log {
debug!("FATAL: PoX reward set did not specify signer set in Nakamoto");
} else {
error!("FATAL: PoX reward set did not specify signer set in Nakamoto");
}
err_or_debug!(
debug_log,
"FATAL: PoX reward set did not specify signer set in Nakamoto"
);
return Err(Error::PoXAnchorBlockRequired);
}

Expand Down
4 changes: 0 additions & 4 deletions stackslib/src/chainstate/nakamoto/coordinator/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,6 @@ fn advance_to_nakamoto(
)
.unwrap();

// use the signing key of addr, otherwise the test stackers
// will not stack enough for any single signing key
// let signing_key = StacksPublicKey::from_private(&private_key);

for sortition_height in 0..11 {
// stack to pox-3 in cycle 7
let txs = if sortition_height == 6 {
Expand Down
3 changes: 1 addition & 2 deletions stackslib/src/chainstate/nakamoto/signer_set.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// Copyright (C) 2013-2020 Blockstack PBC, a public benefit corporation
// Copyright (C) 2020-2023 Stacks Open Internet Foundation
// Copyright (C) 2024 Stacks Open Internet Foundation
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
Expand Down
2 changes: 1 addition & 1 deletion stackslib/src/net/api/getstackers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl GetStackersResponse {
burnchain,
sortdb,
tip,
false,
true,
).map_err(
|e| format!("Could not read reward set. Prepare phase may not have started for this cycle yet. Cycle = {cycle_number}, Err = {e:?}")
)?;
Expand Down
2 changes: 1 addition & 1 deletion stackslib/src/net/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ impl StacksHttp {
self.register_rpc_endpoint(
getstackerdbmetadata::RPCGetStackerDBMetadataRequestHandler::new(),
);
self.register_rpc_endpoint(getstackers::GetStackersRequestHandler::default());
self.register_rpc_endpoint(
gettransaction_unconfirmed::RPCGetTransactionUnconfirmedRequestHandler::new(),
);
Expand All @@ -119,7 +120,6 @@ impl StacksHttp {
self.register_rpc_endpoint(postmicroblock::RPCPostMicroblockRequestHandler::new());
self.register_rpc_endpoint(poststackerdbchunk::RPCPostStackerDBChunkRequestHandler::new());
self.register_rpc_endpoint(posttransaction::RPCPostTransactionRequestHandler::new());
self.register_rpc_endpoint(getstackers::GetStackersRequestHandler::default());
}
}

Expand Down