Skip to content

Commit

Permalink
feat: 📝 implement cometstub crate (work-in-progress)
Browse files Browse the repository at this point in the history
this commit introduces a new library, in `crates/test/`. this library
contains a mock implementation of cometbft, for use in cargo integration
tests.

* this does NOT add the `penumbra-cometstub` crate to the list of
  crates included in the rust documentation in
  `deployments/scripts/rust-docs`. the `penumbra-tct-property-test`
  crate was also not included in that list at the time of writing.

/!\ ------------------------------------------------------- /!\
/!\ NOTE: this is a rolling work-in-progress.               /!\
/!\ this branch will be force-pushed frequently until it is /!\
/!\ ready for review. proceed accordingly!                  /!\
/!\ ------------------------------------------------------- /!\

NOTE 24-01-02: i have brought over a test from
`core/app/src/tests/spend.rs`. currently, it panics because proving keys
could not be loaded. printlns and panics have been left to point out
how far we can get through that test before failing. track down the core
of this issue next week.

use this command to see it break:

```
cargo watch -Bc -x 'test -p penumbra-cometstub spend_happy_path'
```
  • Loading branch information
cratelyn committed Feb 6, 2024
1 parent 912d725 commit 1918429
Show file tree
Hide file tree
Showing 12 changed files with 1,019 additions and 285 deletions.
628 changes: 343 additions & 285 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ members = [
"crates/bin/pclientd",
"crates/bin/pcli",
"crates/wasm",
"crates/test/cometstub",
"crates/test/tct-property-test",
"crates/misc/measure",
"crates/misc/tct-visualize",
Expand Down
1 change: 1 addition & 0 deletions crates/crypto/proof-params/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ impl Deref for LazyProvingKey {

/// Proving key for the spend proof.
pub static SPEND_PROOF_PROVING_KEY: Lazy<LazyProvingKey> = Lazy::new(|| {
println!("XXX(kate) loading spend proving key");
let spend_proving_key = LazyProvingKey::new(spend::PROVING_KEY_ID);

#[cfg(feature = "bundled-proving-keys")]
Expand Down
38 changes: 38 additions & 0 deletions crates/test/cometstub/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[package]
name = "penumbra-cometstub"
version = "0.64.1"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
default = ["std"]
std = ["ibc-types/std"]

[dependencies]
anyhow = "1"
# ed25519 = "2.2.3"
ed25519-consensus = "2.1.0"
ibc-proto = { version = "0.40.0", default-features = false }
ibc-types = { version = "0.11.0", default-features = false }
rand_core = "0.6.3"
sha2 = "0.10.8"
tendermint = "0.34.0"
tendermint-light-client-verifier = "0.34.0"

[dev-dependencies]
cnidarium = { path = "../../cnidarium" }
cnidarium-component = { path = "../../cnidarium-component" }
penumbra-app = { path = "../../core/app" }
penumbra-compact-block = { path = "../../core/component/compact-block" }
penumbra-keys = { path = "../../core/keys" }
penumbra-proof-params = { path = "../../crypto/proof-params", features = [
"bundled-proving-keys",
"download-proving-keys",
] }
penumbra-sct = { path = "../../core/component/sct" }
penumbra-shielded-pool = { path = "../../core/component/shielded-pool", features = ["component"] }
penumbra-txhash = { path = "../../core/txhash" }
rand_chacha = "0.3"
rand_core = "0.6"
tokio = { version = "1.21.1", features = ["full", "tracing"] }
45 changes: 45 additions & 0 deletions crates/test/cometstub/src/abci.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//! ABCI- and ABCI++-related facilities.
//!
//! See the [ABCI++ specification][abci-spec] for more information. See ["Methods][abci-methods]
//! for more information on ABCI methods.
//!
//! [abci-spec]: https://github.com/cometbft/cometbft/blob/main/spec/abci/README.md
//! [abci-methods]: https://github.com/cometbft/cometbft/blob/main/spec/abci/abci++_methods.md
//
// TODO(kate): `tendermint::abci::request` types, stub these out as needed.
// - apply_snapshot_chunk::ApplySnapshotChunk,
// - begin_block::BeginBlock,
// - check_tx::{CheckTx, CheckTxKind},
// - deliver_tx::DeliverTx,
// - echo::Echo,
// - end_block::EndBlock,
// - extend_vote::ExtendVote,
// - finalize_block::FinalizeBlock,
// - info::Info,
// - init_chain::InitChain,
// - load_snapshot_chunk::LoadSnapshotChunk,
// - offer_snapshot::OfferSnapshot,
// - prepare_proposal::PrepareProposal,
// - process_proposal::ProcessProposal,
// - query::Query,
// - set_option::SetOption,
// - verify_vote_extension::VerifyVoteExtension,

use tendermint::{
abci::{request::BeginBlock, types},
block::Round,
Hash,
};

#[allow(dead_code)] // XXX(kate)
pub(crate) fn begin_block() -> BeginBlock {
BeginBlock {
hash: Hash::None,
header: crate::header::header(),
last_commit_info: types::CommitInfo {
round: Round::default(),
votes: vec![],
},
byzantine_validators: vec![],
}
}
102 changes: 102 additions & 0 deletions crates/test/cometstub/src/genesis.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use {
crate::{validator::Validators, State},
tendermint::{block, chain, AppHash, Time},
};

/// The initial conditions for the consensus [`Engine`].
pub struct Genesis {
/// The chain identifier.
chain_id: chain::Id,
/// The timestamp for the initial block.
genesis_time: Time,
/// The initial [`block::Height`].
initial_height: block::Height,
/// The set of validators.
validators: Validators,
/// The initial app hash.
app_hash: AppHash,
// TODO(kate): see `penumbra_app::genesis::AppState`
// - app_state: serde_json::Value,
// TODO(kate): handle consensus parameters later.
// - consensus_params: (),
}

impl Default for Genesis {
fn default() -> Self {
let app_hash: AppHash = b"placeholder-app-hash"
.to_vec()
.try_into()
.expect("infallible");
Self {
genesis_time: Time::unix_epoch(),
chain_id: chain::Id::try_from("penumbra-cometstub").unwrap(),
initial_height: 0_u32.into(),
validators: Validators::default(),
app_hash,
}
}
}

impl Genesis {
/// Returns a new, default [`Genesis`] object.
///
/// Use the builder-style `with_` methods to override particular parts of the genesis state.
pub fn new() -> Self {
Self::default()
}

/// Consumes this genesis information and returns a new [`State`].
//
// TODO(kate): what do we need at the start? avoid recreating a whole genesis file.
// use a single validator key, no arbitrary genesis height, simple.
//
// TODO(kate): perhaps this should also *generate* the first block. makes the state object
// much nicer to work with going forward.
pub fn into_state(self) -> (State, tendermint::Block) {
let Self {
genesis_time: _, // XXX(kate): where do we put this? `next_block`
chain_id,
initial_height,
validators,
app_hash,
} = self;

let state = State {
chain_id,
initial_height,
last_block: None,
validators,
app_hash,
last_results_hash: None,
};
let block = State::generate_block();

(state, block)
}

pub fn with_chain_id(self, chain_id: chain::Id) -> Self {
Self { chain_id, ..self }
}

pub fn with_genesis_time(self, genesis_time: Time) -> Self {
Self {
genesis_time,
..self
}
}

pub fn with_initial_height(self, initial_height: block::Height) -> Self {
Self {
initial_height,
..self
}
}

pub fn with_validators(self, validators: Validators) -> Self {
Self { validators, ..self }
}

pub fn with_app_hash(self, app_hash: AppHash) -> Self {
Self { app_hash, ..self }
}
}
36 changes: 36 additions & 0 deletions crates/test/cometstub/src/header.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//! Facilities for generating tendermint [`Header`]s
use tendermint::{
account,
block::{self, Header},
chain,
validator::Set,
AppHash, Hash, Time,
};

pub(crate) fn header() -> Header {
let validators_hash = Set::new(vec![], None).hash();
Header {
version: block::header::Version { block: 0, app: 0 },
chain_id: chain::Id::try_from("test").unwrap(),
height: block::Height::default(),
time: Time::unix_epoch(),
last_block_id: None,
last_commit_hash: None,
data_hash: None,
validators_hash,
next_validators_hash: validators_hash,
consensus_hash: Hash::None,
app_hash: app_hash(),
last_results_hash: None,
evidence_hash: None,
proposer_address: account::Id::new([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]),
}
}

// TODO(kate): informalsystems/tendermint-rs#1243
fn app_hash() -> AppHash {
AppHash::try_from(vec![1, 2, 3]).expect("AppHash::try_from is infallible")
}
Loading

0 comments on commit 1918429

Please sign in to comment.