Conversation
mskrzypkows
left a comment
There was a problem hiding this comment.
One comment left, LGTM in general. Will you ask claude to review it?
emlautarom1
left a comment
There was a problem hiding this comment.
The golden test matching logic is no particularly good, specially since it does not show where the mismatch is located in case there is one. We can revisit this latter for improvements but I don't intend to block this.
| .map_err(CreateClusterError::DefinitionError)?; | ||
|
|
There was a problem hiding this comment.
No need for explicit map_err
| String::from_utf8_lossy(actual), | ||
| String::from_utf8_lossy(&expected), |
There was a problem hiding this comment.
Do not parse as utf8, compare the bytes directly:
| String::from_utf8_lossy(actual), | |
| String::from_utf8_lossy(&expected), | |
| actual, | |
| &expected, |
| async fn test_eth1_client() -> EthClient { | ||
| EthClient::new("http://127.0.0.1:8545").await.unwrap() | ||
| } |
There was a problem hiding this comment.
If we need an actual Eth client running then we should use testcontainers to spin one up. If not, make this an empty string so we use the Noop client.
| genesis_timestamp: config.testnet_chain_id.map(|_| { | ||
| u64::try_from(chrono::Utc::now().timestamp()).expect("timestamp fits u64") | ||
| }), |
There was a problem hiding this comment.
Is this intentional? If there is no testnet_chain_id then the timestamp is None, otherwise its the current timestamp (now)?
| if let Some(expected) = expected_err { | ||
| let err = result.unwrap_err(); | ||
| let err_str = format!("{err}"); | ||
| assert!( | ||
| err_str.contains(expected), | ||
| "expected error containing '{expected}', got: {err_str}" | ||
| ); | ||
| return; | ||
| } |
There was a problem hiding this comment.
It would be better to match on the CliError instead of using substrings
|
Claude finished @emlautarom1's task in 5m 12s —— View job Code Review
SummaryThis is a solid port of the Go Bug:
|
Summary
Ports the Go
TestCreateClustertest suite to Rust, covering all majorcreate_clusterflows end-to-end, and fixes several correctness issues uncovered in the process.New tests (
crates/cli/src/commands/create_cluster.rs)A shared
run_test_create_clusterhelper drives all test cases, mirroring the Go test loop. Each case exercisesrun()against a temp directory and asserts:cluster-lock.jsonpassesverify_hashes()andverify_signatures()Test cases covered:
simnetgoerlicustom_testnet_flagscustom_target_gas_limittarget_gas_limitsolo_flow_definition_from_disksolo_flow_definition_from_networksplitkeys--split-existing-keys, keys generated in a temp dirsplitkeys_with_cluster_definitionfour_partial_deposits/two_partial_depositswith_fee_recipient_and_withdrawal_addressesvalidate_defGolden files live in
crates/cli/src/commands/testdata/and can be regenerated withUPDATE_GOLDEN=1 cargo test.Bug fixes
create_cluster::run— calldef.set_definition_hashes()before proceeding with key generation; the hashes were previously unset, causingverify_hashes()to fail.definition.rsdeserialization — validate thatnum_validators == validator_addresses.len()for schema versions v1.5–v1.10; add#[serde(default)]tofee_recipient_address,withdrawal_address, andcompoundingso older JSON examples without those fields still deserialize correctly.lock.rsno_registrationcheck — remove the zero-fee_recipientguard. The Go reference useslen == 0(missing field), not the zero Ethereum address; a legitimately zero fee-recipient is valid. Only an all-zero BLS signature or pubkey indicates a missing registration.cluster-definition-005.json— fix malformed timestamp (stray spaces around:separators).Test plan
cargo test -p pluto-clipasses with all new test cases greenUPDATE_GOLDEN=1 cargo testregenerates golden files without diff