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

fix share difficulty validation - compare stratum server minimum_share_difficulty as unscaled difficulty #3624

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions core/src/pow/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,12 @@ impl ProofOfWork {
}
}

/// Maximum unscaled difficulty this proof of work can achieve
pub fn to_unscaled_difficulty(&self) -> Difficulty {
// using scale = 1 gives "unscaled" value
Difficulty::from_num(self.proof.scaled_difficulty(1u64))
}

/// The edge_bits used for the cuckoo cycle size on this proof
pub fn edge_bits(&self) -> u8 {
self.proof.edge_bits
Expand Down
25 changes: 15 additions & 10 deletions servers/src/mining/stratumserver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ struct State {
// nothing has changed. We only want to create a key_id for each new block,
// and reuse it when we rebuild the current block to add new tx.
current_key_id: Option<keychain::Identifier>,
current_difficulty: u64,
minimum_share_difficulty: u64,
current_difficulty: u64, // scaled
minimum_share_difficulty: u64, // unscaled
}

impl State {
Expand Down Expand Up @@ -379,7 +379,8 @@ impl Handler {
return Err(RpcError::too_late());
}

let share_difficulty: u64;
let scaled_share_difficulty: u64;
let unscaled_share_difficulty: u64;
let mut share_is_block = false;

let mut b: Block = b.unwrap().clone();
Expand All @@ -399,22 +400,25 @@ impl Handler {
return Err(RpcError::cannot_validate());
}

// Get share difficulty
share_difficulty = b.header.pow.to_difficulty(b.header.height).to_num();
// Get share difficulty values
scaled_share_difficulty = b.header.pow.to_difficulty(b.header.height).to_num();
unscaled_share_difficulty = b.header.pow.to_unscaled_difficulty().to_num();
// Note: state.minimum_share_difficulty is unscaled
// state.current_difficulty is scaled
// If the difficulty is too low its an error
if share_difficulty < state.minimum_share_difficulty {
if unscaled_share_difficulty < state.minimum_share_difficulty {
// Return error status
error!(
"(Server ID: {}) Share at height {}, hash {}, edge_bits {}, nonce {}, job_id {} rejected due to low difficulty: {}/{}",
self.id, params.height, b.hash(), params.edge_bits, params.nonce, params.job_id, share_difficulty, state.minimum_share_difficulty,
self.id, params.height, b.hash(), params.edge_bits, params.nonce, params.job_id, unscaled_share_difficulty, state.minimum_share_difficulty,
);
self.workers
.update_stats(worker_id, |worker_stats| worker_stats.num_rejected += 1);
return Err(RpcError::too_low_difficulty());
}

// If the difficulty is high enough, submit it (which also validates it)
if share_difficulty >= state.current_difficulty {
if scaled_share_difficulty >= state.current_difficulty {
// This is a full solution, submit it to the network
let res = self.chain.process_block(b.clone(), chain::Options::MINE);
if let Err(e) = res {
Expand Down Expand Up @@ -484,7 +488,7 @@ impl Handler {
b.header.pow.proof.edge_bits,
b.header.pow.nonce,
params.job_id,
share_difficulty,
scaled_share_difficulty,
state.current_difficulty,
submitted_by,
);
Expand Down Expand Up @@ -563,13 +567,14 @@ impl Handler {
wallet_listener_url,
);

// scaled difficulty
state.current_difficulty =
(new_block.header.total_difficulty() - head.total_difficulty).to_num();

state.current_key_id = block_fees.key_id();

current_hash = latest_hash;
// set the minimum acceptable share difficulty for this block
// set the minimum acceptable share unscaled difficulty for this block
state.minimum_share_difficulty = config.minimum_share_difficulty;

// set a new deadline for rebuilding with fresh transactions
Expand Down