-
Notifications
You must be signed in to change notification settings - Fork 1
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
transaction subset contribution #115
Comments
implemented a simpler algorithm, and merged in #118 to hbbft-performance |
Transaction subset contribution currently works like this: Empirically taking this amount of transaction has shown to be a good compromise between the size of the contribution and producing sufficient overlaps between contributions to produce blocks containing almost all of the transactions on each validator's transaction queue. Note that active validators are all connected with each other and will contain very similar transaction queues. Transactions are selected by sender, all transactions for that sender with valid nonces are included in the contribution. When the block is ready to be assembled the contributions of all validator nodes are collected, flattened into a single list and duplicates eliminated. |
How the individual contributions are assembled is less critical, can be changed at any time. All validator nodes are expected to produce a block with exactly the same transactions in exactly the same order. To assure this each validator chosen for a hbbft epoch is given a fixed index which does not change for the duration of the epoch. This means that a validator lucky enough be chosen as first validator (index 0) knows that his transactions will be included first in the block. I recommend mitigating this vulnerability by randomly shuffling the transactions, using the random number generated for that block by hbbft to make the final order of transactions absolutely unpredictable. |
Since random reshuffling is part of the protocol we have to take care the solution is both deterministic and portable. We have to carefully select the function we use and seed it with the random number uniquely generated at block generation, also in a portable manner. The downside of using Rust rand is that it is a language-specific implementation, when porting to other languages the exact same random number generator would have to be re-implemented in the target language. Should we worry about that? Probably not, the alternative would be to come up with a reliable portable solution ourselves. It is worth investigating how the Ethereum implementation is using random number generators and use the same method, ensuring that our use of deterministic random numbers is no less robust than the Ethereum client itself. |
Since the random number generated by the hbbft engine is unpredictable our requirements for the deterministic random generator are low. Rust „rand“ offers a good selection of algorithms with varying complexity: Recommendation: |
An interesting option is to use Keccak256 on the hbbft block’s random value as source of deterministic random numbers. |
problem: currently each node sends each transaction to each node.
A transaction has only to be contributed by one node to get included.
first proposal would be to randomly pick transactions.
we have to work with transaction buckets for this achievement:
Propability of transactions inclusion for a full set:
x-Axis: propabillity value for a node
y-Axis: total chance for transaction inclusion
green graph: All 25 contribute - best case
Blue graph: Only 19 nodes contribute.
https://www.desmos.com/calculator/utqdkgtxc5
Propability of transaction inclusion:
x-Axis: number of Nodes
y-Axis: transaction inclusion: probability (1 = 100%)
p - slider: Chance of transaction proposal
https://www.desmos.com/calculator/tyal2zptps
With a transaction proposal chance of 17% we hit 99% transaction inclusion chance. and 97% if only 19 out of 25 nodes contribute.
Transaction Fee buckets
example:
A1 = Account 1
A2 = Account 2
A3 = Account 3
F1= Fee if 1 Gwei
F2= Fee of 2 Gwei
F3= Fee of 3 Gwei
FS= Service Transactions - Fee of 0 Gwei.
N1 = Nonce 1
N2 = Nonce 2
N3 = Nonce 3.
Transactions:
A1F3N1
A1F1N2
A1F1N3
A2F3N2
A2F2N1
A2F1N3
A3FSN1
Would result in the order:
FS
For Service Transactions (allowed transaction with gas fee of zero)
highest prioritized bucket.
F3:
F2:
F1:
Each RNG should pick from the highest gas fee bucket and contribute from those - until the bucket is empty.
Draft for the Data storage behind:
Q: Does the existing architecture already filter out hard Nonce Gaps (Pool vs Queue) "hard nonce gap": Not even a lower payed Transaction does exist. That would help performance wise.
Considerations:
This would automatically solve : #112
The text was updated successfully, but these errors were encountered: