diff --git a/Cargo.lock b/Cargo.lock index e15746f79a..5b74c1d975 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5617,6 +5617,7 @@ dependencies = [ "decaf377-ka", "decaf377-rdsa", "derivative", + "ed25519-consensus", "hex", "ibc-proto", "ibc-types", @@ -5648,6 +5649,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.8", + "tendermint", "thiserror", "tokio", "tracing", diff --git a/crates/core/transaction/Cargo.toml b/crates/core/transaction/Cargo.toml index 534d42259a..0534803a95 100644 --- a/crates/core/transaction/Cargo.toml +++ b/crates/core/transaction/Cargo.toml @@ -68,3 +68,5 @@ proptest = {workspace = true} proptest = {workspace = true} proptest-derive = {workspace = true} serde_json = {workspace = true} +tendermint = {workspace = true} +ed25519-consensus = {workspace = true} diff --git a/crates/core/transaction/tests/generate_transaction_signing_test_vectors.rs b/crates/core/transaction/tests/generate_transaction_signing_test_vectors.rs index 557d4f6a04..ed75db1988 100644 --- a/crates/core/transaction/tests/generate_transaction_signing_test_vectors.rs +++ b/crates/core/transaction/tests/generate_transaction_signing_test_vectors.rs @@ -1,7 +1,8 @@ use std::fs::File; use decaf377::{Fq, Fr}; -use decaf377_rdsa::{SpendAuth, VerificationKeyBytes}; +use decaf377_rdsa::{SigningKey, SpendAuth, VerificationKey, VerificationKeyBytes}; +use ed25519_consensus::SigningKey as Ed25519SigningKey; use penumbra_asset::asset::Id; use penumbra_fee::Fee; use penumbra_keys::keys::{Bip44Path, SeedPhrase, SpendKey}; @@ -10,13 +11,17 @@ use penumbra_num::Amount; use penumbra_proto::DomainType; use penumbra_sct::epoch::Epoch; use penumbra_shielded_pool::{Note, OutputPlan, SpendPlan}; -use penumbra_stake::{Delegate, IdentityKey, Penalty, Undelegate, UndelegateClaimPlan}; +use penumbra_stake::{ + validator, validator::Definition, Delegate, FundingStreams, GovernanceKey, IdentityKey, + Penalty, Undelegate, UndelegateClaimPlan, +}; use penumbra_transaction::{ActionPlan, TransactionParameters, TransactionPlan}; use proptest::prelude::*; use proptest::strategy::ValueTree; use proptest::test_runner::{Config, TestRunner}; use rand_core::OsRng; use std::io::Write; +use tendermint; fn amount_strategy() -> impl Strategy { let inner_uint_range = 0u128..1_000_000_000_000_000_000u128; @@ -135,6 +140,51 @@ fn undelegate_claim_plan_strategy() -> impl Strategy impl Strategy> { + prop::strategy::LazyJust::new(|| SigningKey::::new(OsRng)) +} + +fn consensus_secret_key_strategy() -> impl Strategy { + prop::strategy::LazyJust::new(|| Ed25519SigningKey::new(OsRng)) +} + +fn validator_strategy() -> impl Strategy)> { + (signing_key_strategy(), consensus_secret_key_strategy()).prop_map( + move |(new_validator_id_sk, new_validator_consensus_sk)| { + let new_validator_id = IdentityKey(VerificationKey::from(&new_validator_id_sk).into()); + let new_validator_consensus = new_validator_consensus_sk.verification_key(); + ( + validator::Validator { + identity_key: new_validator_id.clone(), + consensus_key: tendermint::PublicKey::from_raw_ed25519( + &new_validator_consensus.to_bytes(), + ) + .expect("consensus key is valid"), + governance_key: GovernanceKey(new_validator_id_sk.into()), + enabled: true, + sequence_number: 0, + name: "test validator".to_string(), + website: String::default(), + description: String::default(), + funding_streams: FundingStreams::default(), + }, + new_validator_id_sk, + ) + }, + ) +} + +fn validator_definition_strategy() -> impl Strategy { + (validator_strategy()).prop_map(|(new_validator, new_validator_id_sk)| { + let bytes = new_validator.encode_to_vec(); + let auth_sig = new_validator_id_sk.sign(OsRng, &bytes); + Definition { + validator: new_validator, + auth_sig, + } + }) +} + fn action_plan_strategy(fvk: &FullViewingKey) -> impl Strategy { prop_oneof![ spend_plan_strategy(fvk).prop_map(ActionPlan::Spend), @@ -142,8 +192,8 @@ fn action_plan_strategy(fvk: &FullViewingKey) -> impl Strategy