This is intended as a possible blueprint for abstracting over p2p sources. The current issue is that there are many corner cases in how raw p2p streams are transformed into a stream of block's of items.
Ideally we would have a single source of truth which does this robustly. This PR is an attempt at implementing this for transactions -- however it should be possible to extrapolate this to all streams (maybe excluding headers - but since those are already "blockified" they matter less).
This PR introduces three things, the first two being fairly minor but still nice to consider
PartialReceipt as a wrapper around Receipt. p2p receipts aren't complete ito information as we require the transaction index - which is only available after blockification. However, constantly adding new types is cumbersome, so this is a neat way of "hiding" the data until it is completed.
limit the stream from p2p client. I think ideally this would only perform a single stream attempt from one random peer. This moves the retry logic etc out to sync which simplifies things.
A single TransactionSource which can be spawned as either tracking or checkpoint mode, utilising the same underlying code.
Elaborating on (3) as that's the actual core idea
It should be possible to abstract out all transaction specific parts into one or more traits. Similarly, (1) should also be abstractable in the same way - the only real difference is which protocol is used - just create a StreamKind enum and abstract over that.
I would suggest excluding headers, though it should also be possible to shoehorn them in here.. but probably not needed.
Something to also consider is that something like the state diffs probably want a different output format than Vec<T> -- that could be built into the abstraction, or just handled by the following stage. Similarly, the counting will need to be specialised, I don't think state diff counts are a 1-1 mapping. But this is easily solved via fn count(&T) -> usize method.
Example of the abstraction trait
trait Source {
type Input;
// Defines the stream string to pass to p2p.
const KIND: StreamKind;
fn count(&Self::Input) -> usize;
}
This is intended as a possible blueprint for abstracting over p2p sources. The current issue is that there are many corner cases in how raw p2p streams are transformed into a stream of block's of items.
Ideally we would have a single source of truth which does this robustly. This PR is an attempt at implementing this for transactions -- however it should be possible to extrapolate this to all streams (maybe excluding headers - but since those are already "blockified" they matter less).
This PR introduces three things, the first two being fairly minor but still nice to consider
PartialReceipt
as a wrapper aroundReceipt
. p2p receipts aren't complete ito information as we require the transaction index - which is only available after blockification. However, constantly adding new types is cumbersome, so this is a neat way of "hiding" the data until it is completed.TransactionSource
which can be spawned as either tracking or checkpoint mode, utilising the same underlying code.Elaborating on (3) as that's the actual core idea
It should be possible to abstract out all transaction specific parts into one or more traits. Similarly, (1) should also be abstractable in the same way - the only real difference is which protocol is used - just create a
StreamKind
enum and abstract over that.I would suggest excluding headers, though it should also be possible to shoehorn them in here.. but probably not needed.
Something to also consider is that something like the state diffs probably want a different output format than
Vec<T>
-- that could be built into the abstraction, or just handled by the following stage. Similarly, the counting will need to be specialised, I don't think state diff counts are a 1-1 mapping. But this is easily solved viafn count(&T) -> usize
method.Example of the abstraction trait