Memoize the signature algorithm in Transaction#8590
Memoize the signature algorithm in Transaction#8590siladu wants to merge 2 commits intobesu-eth:mainfrom
Conversation
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
Signed-off-by: Simon Dudley <simon.dudley@consensys.net>
There was a problem hiding this comment.
I was looking a bit more closely at SignatureAlgorithmFactory::getInstance and there is a setInstance method which basically does the same thing as the memoize. I think we should use that instead to set it everywhere across the board.
I wonder if we are missing any initialization step to set the factory to the default signing algorithm?
|
This PR speeds up the prune subcommand from taking 6+ days (ongoing) to take around 5 minutes for the 15 million pre-merge mainnet blocks on a Standard_D4s_v5. This is a similar performance to skipping the call to getBlockBody entirely. TEST: This PR used with prune-pre-merge-blocks - Load blockBodies and prune transaction indexes as well as block bodies CONTROL: Prune block bodies, skip pruning transactions indexes (i.e. skip calling getBlockBody to get the transaction hashes) |
|
Yeah, I think the fact that the initialization is now static, and it is a singleton, I don't see the need of using memoize. |
|
I would like to address to wider static issue in another PR as it is all over the codebase |
|
Not sure to understand your comment @siladu. With this PR, the SIGNATURE_ALGORITHM initialization is now static, and as it is a singleton, there is no need to use memoize. |
What Even the comment in Take a look at examples from |
|
We should really think if we shouldn't just deprecate the R1 curve from the SignatureAlgorithm. It was added because of compliance reasons for institutions, but no wallet or frontend library supports it AFAIK. So not sure if anybody really uses it nowadays. Maybe @matthew1001 knows if anybody is using it in production. |
Since this pattern is used in quite a few places: https://github.com/search?q=repo%3Ahyperledger%2Fbesu%20memoize(SignatureAlgorithmFactory%3A%3AgetInstance)&type=code I think we should wholesale refactor this pattern and use the SIGNATURE_ALGORITHM as a singleton as suggested. We actually already set it on startup: https://github.com/hyperledger/besu/blob/14cdd1f618da9d31e70629c2707c0d2d47b28334/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java#L2671 But I think the impact for some of these use cases would be for anyone using the R1 curve in various parts of Besu, so makes sense to consider this separately I think. |
How much code is required to continue supporting SECP256R1? If it's just another constant in a source file I think I'd suggest leaving it for now. We just happened to have a conversation with an HSM vendor recently who was talking about SECP256R1 as being preferred over Memoizing it feels like the right trade off given the performance benefits described in the PR. We might still find someone using e.g. an HSM for some transactions and a different signer for others - but that feels much less likely |
|
I will close this PR, will explain in next comment, but for posterity since tests were complete, here's the results: TL;DR no difference to mainnet performance. I ran two rounds of testing using Standard_D8as_v5: 3 control versus 3 test BONSAI + CHECKPOINT mainnet syncs. First set: Second set: |
|
After further investigation, it turns out this issue is specific to the The normal besu command executes this which sets the instance: The subcommands override the run() method so it doesn't execute this setup code. Closing this PR in favour of
I will leave removal of R1 as a separate conversation |

** Testing ongoing **
Profiling the prune-pre-merge-blocks subcommand e255296 highlighted a performance issue during
getBlockBody -> TransactionDecoder.decodeRLP -> Transaction<init>The subcommand is loading (for mainnet 15million) block bodies and decoding their transactions in order to get the transactions hashes to prune.
You can see that nearly all the time spent in getBlockBody is loading the signature algorithm. Perhaps this impacts other Besu operations beyond the pruning subcommand.
We also save 8 bytes of memory for every Transaction (4 bytes for the
signatureAlgorithmobject reference + 4 byte offset)Previously:
With this PR: