Modularity and Testing: Case Study of the Miner Loop Optimizations #3345
gregorycoppola
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Introduction
The recent work on optimizing the miner loop’s iteration of the mempool (#3326, #3337) has been interesting on many fronts.
One question which has come up is:
The options that have been considered we will call:
Iterator
DAG Representation of Mempool Iterator
The “modular” approach discussed here represents the iteration implicit in
iterate_candidates
as it is in #3337 into a directed acyclic graph-structured pipeline, where each stage uses typeIterator
. Blue boxes represent iterators ofMempoolTxMinimalInfo
objects, and the green box represents an iterator ofStacksTransaction
. The orange circle represents an end result.Functions
The function modules depicted are:
Iterator
from the databaseMinimalTxInfo
intoStackTransaction
by deserializingTesting
“Modular” Testing
The main benefit of using an
Itetator
pattern for testing is that one can write very specific tests for each module.In this case, we can individually test:
“Black Box” Testing
By putting the entire logic of this pipeline into a single method, we are creating a “black box”, in which the individually separable operations in the DAG formulation can no longer be tested individually, but must be tested all together.
For example, if we want to test the caching of nonce checks, this has to be done in the presence of the random mixing. There is currently no parameter for the random number generator in
iterate_candidates
, and adding one just for testing clutters the interface.Dimensions of “Modularity”
There are two dimensions on which we can measure modularity:
Iterator
The Borrow Checker
The translation of #3337 into a formulation that uses only
Iterator
got further than I initially thought: #3344. I was able to capture the lifetime ofrusqlite::Connection
by using the type:Iterator<Item=M> + 'connection
However, there was ultimately a case in which the translation of #3337 into an abstract iterator framework required, and using the
stacks-node
codebase as it is, would require over-ruling the borrow checker:This is an interesting example because it shows a concrete historical case from
stacks-node
in which something we do approve of as working (#3337) will be over-ruled in a different formulation (#3344) by the borrow-checkers rule against multiple borrows.In other words, there are cases on a single-core machine where some object can be borrowed as mutable multiple times, and this is in fact the desired behavior.
Beta Was this translation helpful? Give feedback.
All reactions