Skip to content
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

Tracking issue: 🤝 mock consensus engine for App tests #3588

Closed
cratelyn opened this issue Jan 8, 2024 · 11 comments
Closed

Tracking issue: 🤝 mock consensus engine for App tests #3588

cratelyn opened this issue Jan 8, 2024 · 11 comments
Assignees
Labels
A-mock-consensus Area: Relates to the mock consensus engine C-enhancement Category: an enhancement to the codebase E-multi-week

Comments

@cratelyn
Copy link
Contributor

cratelyn commented Jan 8, 2024

💭 background and motivation

currently, writing complete end-to-end integration tests for Penumbra is
difficult. moreover, we don't have a better alternative strategy for testing the core App type.

currently, the smoke-test.sh script performs the steps needed
to run integration tests of the system, including:

  • generate testnet configuration
  • start a cometbft process
  • start a pd process
  • run pclientd integration tests against the local test network
  • run pcli integration tests against the local test network
  • confirm the test network is still running

because these integration tests assume a test network including pd and
cometbft is running locally, these tests must run serially, and must spend
time waiting for new blocks to be generated.

additionally, this means we must under-handedly make use of the #[ignore]
attribute to prevent these tests from running (and failing) alongside unit
tests when commands like cargo test --workspace are run.

see CometMock for a mock implementation of CometBFT implemented
in Go. see #2771 for previous work in this space integrating with CometMock.

📐 overview

this state of affairs would be improved if we had a mock implementation of the
consensus engine (CometBFT) that would allow #[test] functions to
generate ABCI messages. this mock implementation should function as a drop-in
replacement for CometBFT from the perspective of the pd daemon.

this mocking library should additionally expose some "meta" interfaces. to allow us
to write integration tests including things like:

  • manipulating the timer used for generating blocks, so that edge-cases
    involving e.g. expiry may be exercised.
  • commit double-signing violations
  • [...] (this list is non-exhaustive at the time of writing)

this will allow us to run integration tests faster, write them more easily,
and generally improve our ability to make assurances about the correctness
of our software.

📐 requirements & design guidelines

(this will go into crate-level documentation at some point)

  • the mock consensus engine should be application agnostic. that means it should not depend on penumbra-* crates. (#3810)

  • the mock consensus engine is built to drive a consensus service C: Service<ConsensusRequest, Response = ConsensusResponse, Error = BoxError>

🔗 related work

🔜 future work

this is a large project, and the extension and maintenance of this library will be an ongoing project. here are things that we ought to do someday, but won't be considered requirements for this issue to be closed.

❌ out-of-scope

things we will not be doing, and other closed tickets:

👓 further reading

@cratelyn cratelyn added C-enhancement Category: an enhancement to the codebase A-tooling Area: developer tooling for building Penumbra itself labels Jan 8, 2024
@cratelyn cratelyn self-assigned this Jan 8, 2024
@cratelyn cratelyn removed this from Testnets Jan 8, 2024
@cratelyn cratelyn added this to Penumbra Jan 8, 2024
@github-project-automation github-project-automation bot moved this to 🗄️ Backlog in Penumbra Jan 8, 2024
@cratelyn cratelyn moved this from 🗄️ Backlog to 🏗 In progress in Penumbra Jan 8, 2024
@erwanor erwanor added this to Testnets Jan 8, 2024
@erwanor erwanor moved this to Tracking Issues in Testnets Jan 8, 2024
@erwanor erwanor changed the title 🔬 mock consensus engine for integration tests Tracking issue: mock consensus engine for integration tests Jan 8, 2024
@erwanor erwanor changed the title Tracking issue: mock consensus engine for integration tests Release tracking issue: mock consensus engine for integration tests Jan 8, 2024
@conorsch conorsch changed the title Release tracking issue: mock consensus engine for integration tests Tracking issue: mock consensus engine for integration tests Jan 8, 2024
@cratelyn
Copy link
Contributor Author

cratelyn commented Jan 9, 2024

update 2024-01-09: in #3592 and in some direct conversations, we discussed the desire to address #3588 using two crates: (1) a core library that provides the ability to generate block headers, and (2) an in-memory consensus engine with facilities to manipulate time.

after some further reading, i believe it makes sense to keep #3597 focused on (1), rather than attempting to completely address #3588 in one PR. this core library should be able to generate valid block headers that can be successfully parsed by a real light client library. (tendermint-light-client-verifier seems promising for this)

today i spent time reading through the broad strokes of how the protobuf types and .proto files are used to generate Rust types that can be (de)serialized and used by core application logic. i also spent some time today learning more about how the cnidarium crate's StateRead and StateWrite traits are extended by the penumbra-chain and penumbra-ibc libraries in crates/core/component. the latter part led me to some the message handling code, which interacts with cometbft/tendermint headers.

at this point i'm still getting a lay of the land, but i feel like i am gaining a much clearer picture of what work is to come. tomorrow i'll meet up with @avahowell to answer questions i've accrued concerning IBC, and spend some time working on stubs to generate a valid tendermint block header.


🍞 🔗 helpful links for future reference

@cratelyn
Copy link
Contributor Author

cratelyn commented Jan 22, 2024

update 2024-01-22:

today i continued to push pr #3597 along. i am at the point where i can almost feed output into the tendermint-light-client-verifier.

as of now, i have a lightweight validator system defined, defaulting to a single validator. i have my consensus state defined, modeled after (some of) comet's own internal consensus state.

there is still much more to do, but it's tremendously exciting to see this library progressing past the embryonic stages. h/t to conor for showing me some relevant plumbing in the pd daemon today as well.

that's all from me for this week, i will see you all on monday 💐

- me, #status channel in discord

with my draft pr (#3597) further along, i am going to pivot focus to work on #3627 this week. i'll resume work on this issue afterwards.

@cratelyn
Copy link
Contributor Author

today @hdevalence linked me to #1664. this is a great issue outlining the larger goals and direction of our testing facilities. linking here, for future reference.

@cratelyn cratelyn changed the title Tracking issue: mock consensus engine for integration tests Tracking issue: 🤝 mock consensus engine for integration tests Jan 31, 2024
@aubrika aubrika moved this from In progress to 🗄️ Backlog in Penumbra Feb 2, 2024
@aubrika aubrika removed this from Testnets Feb 5, 2024
cratelyn added a commit that referenced this issue Mar 12, 2024
see #3913, #3973 and #3588. this is a second attempt, following up on
#3980.

#### 🔭 background

NB: the difference between this and #3679 is that the latter (_which ran
afoul of a regression_) would have `penumbra-app` create a `Routes`,
that we would
[add](https://github.com/penumbra-zone/penumbra/pull/3679/files#diff-fbc4204ceb976c8cb30ed06168e2476700bae21bfd803e26281b2d026194d430R204)
to the builder (_which stays in `pd`_). here, i'm not trying to make
that cut between `Router` and `Routes`, and am attempting to hoist the
whole thing out of `pd`, without making changes to how we interact with
`tonic`. my aim is for us to be able to move this, without running into
that bug (#3697) again.

NB: after running into problems in #3980, i found a way to easily
reproduce the issue locally. my belief was that something related to our
dependencies' cargo features was at play. rather than isolate the issue,
it was easier to rewrite this (_it's just code motion, after all_) while
running some of the network integration tests in a loop.

unlike #3980, this moves the rpc server into `penumbra-app`, per
#3980 (comment)

#### 👁️ overview

we would like to use the rust view server in mock consensus tests. in
order to run the `penumbra_view::ViewServer` however, we need to spin up
the corresponding grpc endpoint for it to connect to.

this branch performs a bit of code motion, moving the `grpc_server` out
of `pd` and into `penumbra-app`. there will likely be other functional
changes to the code in question before we can use it in those tests, but
this PR is interested in moving that code into a place where our tests
can rely upon it.
cratelyn added a commit that referenced this issue Mar 12, 2024
fixes #3933.

this introduces a `fast_forward` method to a test node, allowing tests
using the mock consensus engine (#3588) to fast forward a certain number
of blocks.

the existing `mock_consensus_can_send_a_sequence_of_empty_blocks` test
is rewritten to make use of this method.

this is done in service of #3995.

---

* #3588
* #3933
* #3995
cratelyn added a commit that referenced this issue Mar 12, 2024
)

fixes #3936. based upon #4002. see #3588.

this changes the type of the block builder's `data`, allowing it to be
implicitly kept empty. this is useful when e.g. fast forwarding a number
of blocks _(see #4002)_. this spares us the need to call
`with_data(vec![])`, and additionally means that the block builder is
never in an uninitialized state _(making #4003 needless)._

* #3936
* #4002
* #3588
cratelyn added a commit that referenced this issue Mar 13, 2024
this patches the mock consensus `TestNode::end_block` method so that the
height of these requests does not stay at 1.

this is needed for staking tests, see #3995.

* #3588
* #4001
* #3995
* #3840
cratelyn added a commit that referenced this issue Mar 15, 2024
this patches the mock consensus `TestNode::end_block` method so that the
height of these requests does not stay at 1.

this is needed for staking tests, see #3995.

* #3588
* #4001
* #3995
* #3840
cratelyn added a commit that referenced this issue Mar 15, 2024
this patches the mock consensus `TestNode::end_block` method so that the
height of these requests does not stay at 1.

this is needed for staking tests, see #3995.

* #3588
* #4001
* #3995
* #3840
cratelyn added a commit that referenced this issue Mar 18, 2024
fixes #3966. fixes #3908. fixes _part of_ #3995.

this branch introduces the first steps towards mock consensus (#3588)
testing of the staking component (#3845).

this defines a validator after genesis, and then shows that it does
_not_ enter the consensus set. #3966 is addressed in this branch so that
the existing genesis validator correctly enters the consensus set, and
so that we can successfully progress to the second epoch.

subsequent changes will exercise delegating to this validator in the
`mock_consensus_can_define_and_delegate_to_a_validator`.

#### ✨ changes

* alters `with_penumbra_auto_app_state` so that it adds an allocation of
delegation tokens to the shielded pool component's genesis content.

* extends `generate_penumbra_validator` so that it generates a real
spend key, and returns an `Allocation` for the generated validator.
_(see #3966)_

* adds a new `mock_consensus_can_define_and_delegate_to_a_validator`
test that defines a post-genesis validator. _(see #3908)_

* defines a new `ConsensusIndexRead::get_consensus_set()` method, which
collects all of the identity keys returned by `consensus_set_stream`.

* lowers the events in
`penumbra_mock_consensus::block::Builder::execute()` to trace-level
events.

* `penumbra_mock_consensus::builder::Builder` will now log a warning if
values may be errantly rewritten by the builder methods.

* `TestNode::fast_forward` sets its `i` span field to `1..n`, rather
than `0..n-1`.

---

#### :link: related

* #4009
* #4010
* #4011
* #4017
* #4027
* #4028
* #4029
* #3966
* #3908
* #3588

---------

Co-authored-by: Henry de Valence <hdevalence@penumbralabs.xyz>
cratelyn added a commit that referenced this issue Apr 8, 2024
fixes #3937.

* #3937
* #3588

this adds a `two_validators` method to the test node builder, so that
tests may set up a test node that has two validator keys.
cratelyn added a commit that referenced this issue Apr 8, 2024
fixes #3937.

* #3937
* #3588

this adds a `two_validators` method to the test node builder, so that
tests may set up a test node that has two validator keys.
cratelyn added a commit that referenced this issue Apr 9, 2024
fixes #3937.

* #3937
* #3588

this adds a `two_validators` method to the test node builder, so that
tests may set up a test node that has two validator keys.
cratelyn added a commit that referenced this issue Apr 9, 2024
fixes #4050. see also #3588.

this introduces a test case that demonstrates that transactions'
validator definition actions must have a valid authentication signature,
or the validator will not be added to the set of known validators.
@cratelyn cratelyn moved this from Backlog to In progress in Penumbra Apr 9, 2024
cratelyn added a commit that referenced this issue Apr 9, 2024
fixes #4181. see #3588.

this makes a pass through the `penumbra-mock-consensus` library and
further documents various interfaces. one other small tweak, logging a
warning if a caller may be inadvertently discarding transactions, is
made while we are here.

these docs may be rendered by running:

`cargo doc --package penumbra-mock-consensus --open`

---------

Co-authored-by: Conor Schaefer <conor@penumbralabs.xyz>
erwanor pushed a commit that referenced this issue Apr 11, 2024
fixes #4050. see also #3588.

this introduces a test case that demonstrates that transactions'
validator definition actions must have a valid authentication signature,
or the validator will not be added to the set of known validators.

- [x] If this code contains consensus-breaking changes, I have added the
"consensus-breaking" label. Otherwise, I declare my belief that there
are not consensus-breaking changes, for the following reason:

  > this is a test case.
conorsch pushed a commit that referenced this issue Apr 11, 2024
see #3588. follows #4184 and #4181.

this takes a pass through the shared, Penumbra-specific test
infrastructure for mock consensus tests. notably, this decomposes
`init_chain.rs`, which has now become somewhat redundant with the
existence of other more involved tests of e.g. validator uptime
tracking.

this also cleans up some unused imports, guards against future
occurrences of that issue (_sharing code in `tests/` files is awkward_),
and decomposes the `common/mod.rs` file into some distinct standalone
components.

this also belatedly removes the `common::start_test_node()` helper. at
some point (_i was unable to find the link_) it was suggested that we
refrain from a shared setup helper like that. this branch removes that
helper, and updates its call-sites.

this branch is largely code motion, and is intended to be a last bit of
cleanup as we prepare for #3588 to wind down. ❤️

---------

Co-authored-by: Henry de Valence <hdevalence@penumbralabs.xyz>
@github-project-automation github-project-automation bot moved this from In progress to Done in Penumbra Apr 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-mock-consensus Area: Relates to the mock consensus engine C-enhancement Category: an enhancement to the codebase E-multi-week
Projects
Archived in project
Status: Future
Development

No branches or pull requests

2 participants