fuel-core icon indicating copy to clipboard operation
fuel-core copied to clipboard

Block Producer WIP

Open Voxelot opened this issue 2 years ago • 3 comments

Initial base for the block producer service WIP

Leveraging ports & adapters architecture to unblock development from depending on other components & also to improve composability & testability.

The main principle behind the P&A design is to allow the component to specify all external dependencies via its' own traits which don't need to be depended on by others. Fuel Core can provide adapter impls at a later time when feasible, while allowing the block producer to be logically implemented and functionally tested in the meantime as a self-contained unit.

I'm also experimenting with the service design a bit, it seems like treating the service as a dummy wrapper for spawning the stateful block producer task makes the borrow checker happier and avoids the need for mutexes and other concurrency primitives.

Voxelot avatar Jun 14 '22 08:06 Voxelot

What is intention behind this change?

rakita avatar Jun 14 '22 10:06 rakita

Most of this PR is just additional logic for the block producer. I brought in the P&A concepts as I went along because I ran into blockers directly integrating with the relayer and txpool since they aren't done yet.

Then I realized the ports pattern could be used to start developing the other modules in parallel so that we don't have to serialize the development of these modules based on their order of dependencies. I'd consider it complementary to the event-driven arch. It's purely an additional abstraction which makes the core domain logic of the modules more pure, testable, and easier to follow. For example, the impl for the core domain logic of block production is already there and fits into a 30 LOC function.

If we go with this P&A approach in the other modules, we'll basically need to do two passes. The first pass is building the core domain logic and testing all the edge cases, and then the second pass would be simply implementing the adapters in the main fuel-core crate and injecting them into the appropriate modules.

I'll get more of this wired up and then make an official design proposal using this as an example.

Voxelot avatar Jun 14 '22 20:06 Voxelot

Why i asked that directly for intention is that I was not sure if you looked at how it is now, and for example how fuel-relayer did this, as it does rely on database and fuel-importer and can be standalone tested: https://github.com/FuelLabs/fuel-core/blob/f549a3f315380202dec60893a14bd7c9990c27e0/fuel-relayer/src/service.rs#L26-L27 For relayer channels, I need to move them from new function but the idea is there.

same for txpool: https://github.com/FuelLabs/fuel-core/blob/887f9443d9a362cb150967c1953d82b68c515ea1/fuel-txpool/src/service.rs#L31

Abstraction is done over channel message enums.

Maybe there is a need for having new, init and start functions. new to create, init to bind channels, and start/stop to stop and start service.

rakita avatar Jun 15 '22 10:06 rakita

As discussed with @Voxelot earlier today, this PR now contains the standalone block producer module with minimal implementation. It will not be used elsewhere in the code yet, but to keep PRs small enough to review, that integration will be done later.

Follow-up PRs will include:

  • Integrating the block producer into Fuel node service
  • Configurable block production trigger https://github.com/FuelLabs/fuel-core/issues/50
  • A minimal block importer, see also https://github.com/FuelLabs/fuel-core/issues/465
  • Proper e2e testing

Dentosal avatar Sep 08 '22 21:09 Dentosal

It appears that we are reintroducing the concept of a prefilled test database in the form of DummyDb in fuel-core-interfaces/src/db/helpers.rs.

We removed all instances of DummyDb in unit tests and replaced it with an empty database that unit tests could instantiate and fill themselves.

Is there a reason we want to reintroduce the DummyDb struct and all its prefilled data?

bvrooman avatar Sep 12 '22 16:09 bvrooman

Is there a reason we want to reintroduce the DummyDb struct and all its prefilled data?

No, the helpers file just slipped by me when merging from master. I'll remove it.

Dentosal avatar Sep 12 '22 16:09 Dentosal

Just pushed a bunch of changes:

  • No longer using the mpsc channels, using a simpler async trait approach for the block producer instead.
  • Cleaned up the integ test to no longer require fuel-core by using a mockdb for the txpool
  • No longer use a trailing da_height. This just slows down the deposit process and creates a bunch of extra corner cases when selecting transaction from the txpool that contain messages. Instead, the block importer should queue blocks until the local relayer finalized da_height catches up to the pending imported block's da_height. This way the block producer can always use the latest finalized da_height for new blocks since it'll be guaranteed to always be >= the previously imported block's da_height.
  • unit tests!

Voxelot avatar Sep 17 '22 03:09 Voxelot

blocked by: https://github.com/FuelLabs/fuel-tx/pull/189

Voxelot avatar Sep 23 '22 21:09 Voxelot

Blocker cleared. Now this has merge conflicts.

Dentosal avatar Sep 23 '22 21:09 Dentosal

Look good!=) It is hard to read the integration test, but maybe in the future, we will find how to make it more readable=D

I think once the followup tasks are implemented this test should look a lot simpler and not have to simulate as much of the node behavior.

Voxelot avatar Sep 24 '22 00:09 Voxelot