-
Notifications
You must be signed in to change notification settings - Fork 26
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
Extend the BLSCache to add in a rust Pybinding for validate_clvm_and_signature for use in the mempool #637
base: main
Are you sure you want to change the base?
Conversation
Pull Request Test Coverage Report for Build 10267356686Details
💛 - Coveralls |
crates/chia-bls/src/bls_cache.rs
Outdated
@@ -122,9 +129,9 @@ impl BlsCache { | |||
let msgs = msgs | |||
.iter()? | |||
.map(|item| item?.extract()) | |||
.collect::<PyResult<Vec<PyBackedBytes>>>()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the rationale for making this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reverted it back now.
crates/chia-bls/src/bls_cache.rs
Outdated
PyBytes::new_bound(py, key), | ||
PyBytes::new_bound(py, &value.to_bytes()), | ||
))?; | ||
ret.append((PyBytes::new_bound(py, key), value.clone().into_py(py)))?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we talked about going back to using plan bytes
here, since GTElement
doesn't support pickle. (maybe it should in the future, but let's make that a separate PR)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
crates/chia-bls/src/bls_cache.rs
Outdated
@@ -64,7 +71,7 @@ impl BlsCache { | |||
|
|||
// Otherwise, we need to calculate the pairing and add it to the cache. | |||
let mut aug_msg = pk.borrow().to_bytes().to_vec(); | |||
aug_msg.extend_from_slice(msg.as_ref()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect extend_from_slice()
to be more efficient. Is there a good reason to make this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
wheel/generate_type_stubs.py
Outdated
max_cost: int, | ||
constants: ConsensusConstants, | ||
peak_height: int, | ||
cache: Option[BLSCache], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you should pass in the cache here. If we want to make that change, I think it should be considered independently of porting this to rust
wheel/generate_type_stubs.py
Outdated
def get_name_puzzle_conditions( | ||
spend_bundle: SpendBundle, | ||
max_cost: int, | ||
constants: ConsensusConstants, | ||
height: int, | ||
) -> SpendBundleConditions: ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't look like this function is defined in this PR. Did you mean get_conditions_from_spendbundle()
?
It would be good to understand why this wasn't caught by CI as well. Perhaps there's no python test for this function, or we don't run mypy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed the immediate problem, but I agree the testing for the pyi file is lacking
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Manually generating this file is I hope only a temporary solution
Pyo3 is working on automatic type stub generation (though I don't know how we'll do our custom integer types)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we do run mypy
, so I would have expected this to be caught if there was a test attempting to use this function (under either this name or the true name)
max_cost: u64, | ||
constants: &ConsensusConstants, | ||
height: u32, | ||
cache: &Arc<Mutex<BlsCache>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you should pass in the cache here
tests/test_blscache.py
Outdated
for key, value in cached_bls.items(): | ||
assert isinstance(key, bytes) | ||
assert isinstance(value, bytes) | ||
assert isinstance(value, GTElement) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we agreed to these as bytes
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
use std::sync::Arc; | ||
|
||
#[test] | ||
fn test_validate_no_pks() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there seems to be a lot of repetitions across these tests. did you try to factor something out or make it a parameterized test?
result | ||
} | ||
|
||
pub fn u64_to_bytes(val: u64) -> Bytes { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems to be an internal function that probably shouldn't be public/exported
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's used in spendbundle_validation.rs's tests and I suspect will be useful in more places as the Rust ports continue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should probably be pub(crate)
then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
ef93e62
to
ba7da79
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you should revert crates/chia-bls/src/bls_cache.rs
, crates/chia-bls/benches/cache.rs
, crates/chia-bls/src/lib.rs
.
You can define PairingInfo
in wheel/src/api.rs
if you like a name for it.
if !result { | ||
return Err(ErrorCode::BadAggregateSignature); | ||
} | ||
Ok((npcresult, added, start_time.elapsed())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok((npcresult, added, start_time.elapsed())) | |
Ok((npcresult, cache.items(), start_time.elapsed())) |
This change requires you to add the items()
function to the cache (which currently only exists in the python binding). Alternatively (but maybe a bigger change) would be to replace the call to aggregate_verify()
with just a loop over computing the pairings, and return those. There's already an aggregate_verify_gt()
for the signature validation
5893e16
to
a81e3d0
Compare
#[case] parent_id: Vec<u8>, | ||
#[case] puzzle_hash: Vec<u8>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
every test case uses the same values for parent_id
and puzzle_hash
. I don't think you need to make these parameters to the test.
I think you could make msg
a constant in the tests as well, since you don't need to test different values of it (I think).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
result | ||
} | ||
|
||
pub(crate) fn u64_to_bytes(val: u64) -> Bytes { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we already have two copies of this exact function (with this name) in the repository. The other copies are only available to tests however. So I still think it would make sense to make this private (not public) and use one of the existing copies for the test.
match opcode { | ||
AGG_SIG_PARENT => { | ||
expected_result.extend(parent_id.as_slice()); | ||
expected_result.extend(TEST_CONSTANTS.agg_sig_parent_additional_data.as_slice()); | ||
} | ||
AGG_SIG_PUZZLE => { | ||
expected_result.extend(puzzle_hash.as_slice()); | ||
expected_result.extend(TEST_CONSTANTS.agg_sig_puzzle_additional_data.as_slice()); | ||
} | ||
AGG_SIG_AMOUNT => { | ||
expected_result.extend(u64_to_bytes(coin_amount).as_slice()); | ||
expected_result.extend(TEST_CONSTANTS.agg_sig_amount_additional_data.as_slice()); | ||
} | ||
AGG_SIG_PUZZLE_AMOUNT => { | ||
expected_result.extend(puzzle_hash.as_slice()); | ||
expected_result.extend(u64_to_bytes(coin_amount).as_slice()); | ||
expected_result.extend( | ||
TEST_CONSTANTS | ||
.agg_sig_puzzle_amount_additional_data | ||
.as_slice(), | ||
); | ||
} | ||
AGG_SIG_PARENT_AMOUNT => { | ||
expected_result.extend(parent_id.as_slice()); | ||
expected_result.extend(u64_to_bytes(coin_amount).as_slice()); | ||
expected_result.extend( | ||
TEST_CONSTANTS | ||
.agg_sig_parent_amount_additional_data | ||
.as_slice(), | ||
); | ||
} | ||
AGG_SIG_PARENT_PUZZLE => { | ||
expected_result.extend(parent_id.as_slice()); | ||
expected_result.extend(puzzle_hash.as_slice()); | ||
expected_result.extend( | ||
TEST_CONSTANTS | ||
.agg_sig_parent_puzzle_additional_data | ||
.as_slice(), | ||
); | ||
} | ||
AGG_SIG_ME => { | ||
expected_result.extend(coin.coin_id().as_slice()); | ||
expected_result.extend(TEST_CONSTANTS.agg_sig_me_additional_data.as_slice()); | ||
} | ||
_ => {} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rather than computing the expected value programatically, I think it would be easier to read this test (and be confident it's correct) if the expected output was a parameter instead. Since these are binary strings, it could be simplified by either altering the test constants to make the additional data ascii, or to change the messages to be hex and then specify the expected output as hex. Given that the amount will be binary either way, that might be the better option
…Conditions (to enable reusing existing test facilities). Extend the tests to cover the block-generator test cases
39d2d85
to
ffb68ce
Compare
No description provided.