Skip to content
Open
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
40 changes: 22 additions & 18 deletions sv2/channels-sv2/src/server/extended.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,14 @@ where
}
};

if target > max_target {
println!("target: {:?}", target.to_be_bytes());
println!("max_target: {:?}", max_target.to_be_bytes());
return Err(ExtendedChannelError::RequestedMaxTargetOutOfRange);
}
// Clamp to max_target rather than error. The client declared max_target as
// an acceptable difficulty floor, so using it when the initial target would
// otherwise exceed it is always valid.
let target = if target > max_target {
max_target
} else {
target
};

if extranonce_prefix.len() > MAX_EXTRANONCE_PREFIX_LEN {
return Err(ExtendedChannelError::ExtranoncePrefixTooLarge);
Expand Down Expand Up @@ -396,11 +399,14 @@ where
bytes_to_hex(&max_target_bytes)
);

let new_target: Target = target;

if new_target > *requested_max_target {
return Err(ExtendedChannelError::RequestedMaxTargetOutOfRange);
}
// Clamp to max_target rather than error. The client declared max_target as
// an acceptable difficulty floor, so using it when vardiff would otherwise
// exceed it is always valid.
let new_target: Target = if target > *requested_max_target {
*requested_max_target
} else {
target
};

self.nominal_hashrate = new_nominal_hashrate;
self.target = new_target;
Expand Down Expand Up @@ -1604,17 +1610,15 @@ mod tests {
0xff, 0xff, 0xff, 0x00,
]);

// Try to update with a hashrate that would result in a target exceeding the max_target
// new target: 2492492492492492492492492492492492492492492492492492492492492491
// max target: 00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// Update with a hashrate that would compute a target exceeding max_target.
// The channel should clamp to not_so_permissive_max_target instead of erroring.
// calculated target: 2492492492492492492492492492492492492492492492492492492492492491
// max target: 00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
let very_small_hashrate = 0.1;
let result =
channel.update_channel(very_small_hashrate, Some(not_so_permissive_max_target));
assert!(result.is_err());
assert!(matches!(
result,
Err(ExtendedChannelError::RequestedMaxTargetOutOfRange)
));
assert!(result.is_ok());
assert_eq!(channel.get_target(), &not_so_permissive_max_target);

// Test successful update with not_so_permissive_max_target
// new target: 0001179d9861a761ffdadd11c307c4fc04eea3a418f7d687584e4434af158205
Expand Down
40 changes: 22 additions & 18 deletions sv2/channels-sv2/src/server/standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,14 @@ where
}
};

let target: Target = calculated_target;

if target > requested_max_target {
return Err(StandardChannelError::RequestedMaxTargetOutOfRange);
}
// Clamp to max_target rather than error. The client declared max_target as
// an acceptable difficulty floor, so using it when the initial target would
// otherwise exceed it is always valid.
let target: Target = if calculated_target > requested_max_target {
requested_max_target
} else {
calculated_target
};

if extranonce_prefix.len() > MAX_EXTRANONCE_PREFIX_LEN {
return Err(StandardChannelError::ExtranoncePrefixTooLarge);
Expand Down Expand Up @@ -344,11 +347,14 @@ where
bytes_to_hex(&max_target_bytes)
);

let new_target: Target = target;

if new_target > requested_max_target {
return Err(StandardChannelError::RequestedMaxTargetOutOfRange);
}
// Clamp to max_target rather than error. The client declared max_target as
// an acceptable difficulty floor, so using it when vardiff would otherwise
// exceed it is always valid.
let new_target: Target = if target > requested_max_target {
requested_max_target
} else {
target
};

self.target = new_target;
self.nominal_hashrate = nominal_hashrate;
Expand Down Expand Up @@ -1368,17 +1374,15 @@ mod tests {
0xff, 0xff, 0xff, 0x00,
]);

// Try to update with a hashrate that would result in a target exceeding the max_target
// new target: 2492492492492492492492492492492492492492492492492492492492492491
// max target: 00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// Update with a hashrate that would compute a target exceeding max_target.
// The channel should clamp to not_so_permissive_max_target instead of erroring.
// calculated target: 2492492492492492492492492492492492492492492492492492492492492491
// max target: 00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
let very_small_hashrate = 0.1;
let result =
channel.update_channel(very_small_hashrate, Some(not_so_permissive_max_target));
assert!(result.is_err());
assert!(matches!(
result,
Err(StandardChannelError::RequestedMaxTargetOutOfRange)
));
assert!(result.is_ok());
assert_eq!(channel.get_target(), &not_so_permissive_max_target);

// Test successful update with not_so_permissive_max_target
// new target: 0001179d9861a761ffdadd11c307c4fc04eea3a418f7d687584e4434af158205
Expand Down
Loading