-
Notifications
You must be signed in to change notification settings - Fork 305
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: 📝 implement cometstub crate (work-in-progress)
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
Showing
12 changed files
with
581 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
[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 = ["component", "std"] | ||
component = [ | ||
# TODO(kate): are these feature flags needed? maybe. | ||
# "cnidarium", | ||
# "cnidarium-component", | ||
# "penumbra-proto/cnidarium", | ||
# "penumbra-chain/component", | ||
] | ||
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-chain = { path = "../../core/component/chain", features = ["component"] } | ||
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"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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![], | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
//! `penumbra-cometstub` is an in-memory consensus engine for integration tests. | ||
// | ||
// TODO(kate): | ||
// - `tests/ibc_handshake.rs` contains a starter test case to build out. | ||
|
||
pub mod validator; | ||
|
||
mod abci; | ||
mod header; | ||
mod state; | ||
|
||
use { | ||
self::validator::Validators, | ||
tendermint::{block, chain, AppHash, Hash, Time}, | ||
}; | ||
|
||
/// An in-memory consensus engine for integration tests. | ||
/// | ||
/// See the crate-level documentation for more information. | ||
pub struct Engine { | ||
/// Inner consensus state. | ||
#[allow(dead_code)] // XXX(kate) | ||
state: State, | ||
} | ||
|
||
/// Consensus state used by the [`Engine`] to generate [`Block`s][tendermint::Block]. | ||
// | ||
// TODO(kate): make this `pub(crate)`. use Engine as the public layer for the caller. | ||
#[allow(dead_code)] // XXX(kate) | ||
pub struct State { | ||
/// The chain identifier. | ||
chain_id: chain::Id, | ||
/// The initial [`block::Height`]. | ||
initial_height: block::Height, | ||
/// Metadata regarding the last block generated. | ||
last_block: Option<LastBlock>, | ||
/// The set of validators. | ||
validators: Validators, | ||
/// The latest app hash. | ||
app_hash: AppHash, | ||
/// The merkle root of the result of executing the previous block. | ||
last_results_hash: Option<Hash>, | ||
// TODO(kate): handle consensus parameters later. | ||
// consensus_params: (), | ||
// last_height_consensus_params_changed: block::Height, | ||
} | ||
|
||
/// Consensus [`State`] metadata regarding the last block generated. | ||
#[allow(dead_code)] // XXX(kate) | ||
pub struct LastBlock { | ||
height: block::Height, | ||
id: block::Id, | ||
time: 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): handle consensus parameters later. | ||
// - app_state: serde_json::Value, | ||
// - consensus_params: (), | ||
} | ||
|
||
// === impl Engine === | ||
|
||
impl Engine { | ||
/// Returns a new [`Engine`]. | ||
// | ||
// TODO(kate): for now, use a default `Genesis` structure. add a constructor receiving a | ||
// `State` at some point later. | ||
pub fn new() -> Self { | ||
Self { | ||
state: Genesis::default().into_state(), | ||
} | ||
} | ||
|
||
pub fn next_block(&self) -> tendermint::Block { | ||
self.state.next_block() | ||
} | ||
} | ||
|
||
// === impl State === | ||
|
||
impl State { | ||
pub(crate) fn next_block(&self) -> tendermint::Block { | ||
let State { | ||
chain_id, | ||
initial_height, | ||
last_block, | ||
validators, | ||
app_hash, | ||
last_results_hash, | ||
} = self; | ||
|
||
use tendermint::block::header::Header; | ||
use tendermint::Hash; | ||
let header = Header {}; | ||
|
||
todo!("State::next_block"); | ||
} | ||
} | ||
|
||
// === impl Genesis === | ||
|
||
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 { | ||
/// 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 { | ||
let Self { | ||
genesis_time: _, // XXX(kate): where do we put this? `next_block` | ||
chain_id, | ||
initial_height, | ||
validators, | ||
app_hash, | ||
} = self; | ||
|
||
State { | ||
chain_id, | ||
initial_height, | ||
last_block: None, | ||
validators, | ||
app_hash, | ||
last_results_hash: None, | ||
} | ||
} | ||
|
||
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 } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
Oops, something went wrong.