-
Notifications
You must be signed in to change notification settings - Fork 300
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
Add Supranational BLS implementation #2453
Conversation
…aces # Conflicts: # bls/src/main/java/tech/pegasys/teku/bls/BLS.java # bls/src/main/java/tech/pegasys/teku/bls/BLSPublicKey.java # bls/src/test/java/tech/pegasys/teku/bls/BLSPublicKeyTest.java # data/provider/src/main/java/tech/pegasys/teku/api/schema/BLSPubKey.java
# Conflicts: # bls/build.gradle # bls/src/test/java/tech/pegasys/teku/bls/impl/mikuli/hash2g2/ReferenceTests.java
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be keen for @benjaminion to review the BLS specifics as I'm not too familiar with that. Generally looks good otherwise.
The only concern I have is managing the native memory resources to ensure we aren't leaking them. I wonder if we should create a factory class that is the only place we create instances of the SWIG generated classes and automatically adds them to a Cleaner
to ensure they are always cleaned up. Unfortunately you just can't depend on the finalized
method being called even when the system is heavily under memory pressure.
bls/src/main/java/tech/pegasys/teku/bls/impl/blst/BlstBLS12381.java
Outdated
Show resolved
Hide resolved
p2Signature.delete(); | ||
hash.delete(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's at all possible to have the SWIG bindings make these classes Autocloseable
that would be awesome. In any case we should ensure they are deleted regardless of any potential exceptions or errors that occur so would have to use try/finally blocks. It will get really ugly without Autocloseable
.
We're also winding up with a native memory leak because the wrapped BlstSignature
returned has a reference to p2SignatureAffine
but no way to close it and delete that native object. The finalize
method isn't guaranteed to be called in any kind of timely manner so we can't really depend on it.
If we have to depend on automatic cleanup (which may well be the case for things like public keys and signatures that are used outside of the Blst specific code and currently expect to be fully on-heap), we should use java.lang.ref.Cleaner
to do it which is the recommended instead of finalize.
Maybe use AutoCloseable
if possible for the local variables we need to release and then use Cleaner
for the things that are actually returned from this class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't find Autocloseable
feature in SWIG unfortunately. Indeed that would look better.
Revised places with temporary native wrapper instances and add try/catch/finally where appropriate: 913e484
I'll add a general comment later on my thoughts regarding finalize
and cleaning native structs
bls/src/main/java/tech/pegasys/teku/bls/impl/blst/BlstBLS12381.java
Outdated
Show resolved
Hide resolved
bls/src/main/java/tech/pegasys/teku/bls/impl/blst/BlstPublicKey.java
Outdated
Show resolved
Hide resolved
bls/src/test/java/tech/pegasys/teku/bls/impl/blst/BlstPublicKeyTest.java
Show resolved
Hide resolved
bls/src/test/java/tech/pegasys/teku/bls/impl/mikuli/MikuliPublicKeyTest.java
Outdated
Show resolved
Hide resolved
@@ -169,6 +169,7 @@ downloadLicenses { | |||
//JMH-Core is licensed under GPLv2 with the Classpath Exception, which allows us to link it and license the derived work under our license. | |||
'org.openjdk.jmh:jmh-core:1.21': apache, | |||
(group('io.libp2p')): apache, | |||
(group('tech.pegasys')): apache, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably log a ticket to get the license information included in the blst native jar. I can't remember the magic incantation and its not a priority but something we should do when we setup a full CI for it and then we shouldn't need this.
…re and make them private
…BLSPublicKey fromSSZBytes() and fromBytesCompressed() though they are equivalent with current SSZ implementation
…Compressed() though they are equivalent with the current SSZ implementation
bls/src/test/java/tech/pegasys/teku/bls/impl/blst/BlstTest.java
Outdated
Show resolved
Hide resolved
validator/client/src/test/java/tech/pegasys/teku/validator/client/signer/SignerTest.java
Show resolved
Hide resolved
@ajsutton I don't think that Assuming that underlying native structs are of comparable size as their java wrapper objects they are most likely will be GCed at some point. If they are not GCed then it means we are fine with free RAM at the moment and the underlying allocated structures would make huge difference. So this not our case when large native memory chunks are referenced by small Java wrappers and GC is not aware of the real object allocations and don't hurry up collecting them. (as I remember we had the latter issue in Java2D library with direct byte buffers) Here we have pretty simple logic behind finalize. It doesn't involve any interaction with other components as well it doesn't do any blocking operations as well it doesn't throw exceptions. So hitting any complex issue with blocking finalizer thread or leaving hanging object is highly unlikely. As far as I understand the phrase ' I see the following options at the moment:
BTW found this issue with similar discussion: google/or-tools#1040 So this Google lib also uses SWIG and The above is just my vision and I'm not sure of course that these are all correct statements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I flagged a few trivia, but on the basis of mine and Adrian's reviews I am happy to approve this. It's really good to have this done!
I built locally, and all was well. Running locally, I was happy to see
2020-07-30 18:09:48.850+01:00 | beaconchain-async-0 | INFO | BlstBLS12381 | Successfully loaded native BLS library
and my sync speed was about 3x better than with the JVM BLS lib. 🙌
(Caveat: I'm leaving it to @Nashatyrev and @ajsutton to decide whether the finalize()
things is settled. It looks like it has been thought-through in any case.)
…S.aggregateSignatures() -> BLS.aggregate()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still nervous about finalisers but agree that the implementations aren't going to cause deadlocks or other things - just likely that the native memory won't be released as fast as it probably should. As you say they're quite small amounts of memory so shouldn't be an issue.
So I'm happy to merge this.
PR Description
Add Supranational BLS implementation based on highly optimized native BLS-12381 library
For now I forked the Blst repo and made some tweaks for the Java SWIG binding works correctly on all platforms. Will be working with Blst team to resolve them and push upstream.
The Java SWIG wrapper generated classes and manually built native libraries (Windows, Linux, MacOS) are now in the separate repository: https://github.com/Nashatyrev/jblst. Gradle
bintrayUpload
task may be used to build and publish thetech.pegasys:jblst
artifactBy default the
blst
BLS implementation is loaded. If for some reason it fails to load native lib BLS falls back to Mikuli implementation (with aWARN
log)The PR was tested on: Windows, Linux and MacOS
Future tasks to do:
Blst
repo and switch to the mainBlst
repojblst
repo to generate SWIG java wrappers and build native libs from upstreamblst
repo on CI platforms and build the final artifactBLSConstants.VERIFICATION_DISABLED
flag withNoop
BLS implementationTODOs
Import Benchmarks
Before:
After:
BLS Benchmarks
Blst is x7-x9 faster than Mikuli:
Fixes
Fix #2300
Documentation
documentation
label to this PR if updates are required.