-
Notifications
You must be signed in to change notification settings - Fork 10
Flatten bytes class hierarchy #40
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
base: main
Are you sure you want to change the base?
Conversation
|
All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
|
recheck |
81cb3e2 to
46f5de9
Compare
0625d27 to
2dbda56
Compare
1b4e159 to
8a24b0e
Compare
|
After this comment I will make this PR ready to be pulled in without stopping any development on Tuweni v1 as I'm leaving the current I will squash all changes so far and will create an entire new package |
Signed-off-by: Luis Pinto <[email protected]>
Signed-off-by: Luis Pinto <[email protected]>
Signed-off-by: Luis Pinto <[email protected]>
Signed-off-by: Luis Pinto <[email protected]>
Signed-off-by: Luis Pinto <[email protected]>
8a24b0e to
1c641ff
Compare
|
recheck |
Signed-off-by: Luis Pinto <[email protected]>
Signed-off-by: Luis Pinto <[email protected]>
cc29c50 to
dff599a
Compare
macfarla
left a comment
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.
do we need to add a consensys copyright statement? Are both v1 and v2 tests running?
bytes/src/main/java/org/apache/tuweni/v2/bytes/ArrayWrappingBytes.java
Outdated
Show resolved
Hide resolved
bytes/src/main/java/org/apache/tuweni/v2/bytes/ArrayWrappingBytes.java
Outdated
Show resolved
Hide resolved
|
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
|
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
|
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
|
Closed as inactive. Feel free to reopen if this PR is still being worked on. |
| result[i] = this.ints[i] & other; | ||
| } | ||
| return new UInt256(result); | ||
| } |
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.
Bug: Bitwise Operation Errors in UInt Classes
The and, or, and xor methods in both UInt256 and UInt384 classes contain a byte indexing error when operating on Bytes or Bytes32 parameters. The byte offset calculation incorrectly uses the ints array index (i) instead of the bytes parameter index (j), leading to incorrect bitwise results and potential IndexOutOfBoundsException.
Additional Locations (4)
units/src/main/java/org/apache/tuweni/v2/units/bigints/UInt384.java#L457-L464units/src/main/java/org/apache/tuweni/v2/units/bigints/UInt384.java#L487-L494units/src/main/java/org/apache/tuweni/v2/units/bigints/UInt384.java#L519-L526units/src/main/java/org/apache/tuweni/v2/units/bigints/UInt256.java#L637-L644
| fun create(keyPair: SECP256K1.KeyPair, now: Long): Packet { | ||
| val expiration = expirationFor(now) | ||
| val sigHash = createSignature( | ||
| PacketType.ENRRESPONSE, |
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.
| try { | ||
| SHA256Hash.Hash result = SHA256Hash.hash(shaInput); | ||
| try { | ||
| return SHA256Hash.hash(shaInput).bytes(); |
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.
Bug: Double Hashing Causes Memory Leak
The sha2_256 methods (both byte[] and Bytes overloads) compute the hash twice when Sodium is available. The first hash object is stored and destroyed, but a new hash object is created and returned from a second computation, which is then leaked.
Additional Locations (1)
|
This PR was marked stale due to lack of activity. It will be closed in 14 days. |
| checkElementIndex(offset, bytes.length); | ||
| } | ||
| checkLength(bytes, offset); | ||
| return new ArrayWrappingBytes(bytes, offset, bytes.length); |
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.
Bug: Array Wrapper Overruns Bounds: Incorrect Length
The fromArray method creates an ArrayWrappingBytes with bytes.length as the length parameter, which attempts to wrap more bytes than available when offset > 0. This causes the wrapper to extend beyond the array bounds. The length should be SIZE (32 bytes) to correctly wrap exactly 32 bytes starting from the offset, matching the method's documented behavior and the validation performed by checkLength.
| @Override | ||
| public void appendTo(ByteBuffer byteBuffer) { | ||
| byteBuffer.put(this.byteBuffer); | ||
| } |
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.
Bug: Append Ignores Slice Boundaries
The appendTo method puts the entire byteBuffer into the target buffer, ignoring the offset and size() of this wrapper. When a ByteBufferWrappingBytes represents a slice (constructed with offset and length), this appends the wrong bytes. The method transfers from the buffer's current position/limit rather than the intended slice range defined by offset and size().
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.
IMO it's not a bug
Signed-off-by: Luis Pinto <[email protected]>
Signed-off-by: Luis Pinto <[email protected]>
Signed-off-by: Luis Pinto <[email protected]>
ad67e19 to
a4def2a
Compare
Signed-off-by: Luis Pinto <[email protected]>
| private static final int SIZE = 32; | ||
|
|
||
| /** A {@code Bytes32} containing all zero bytes */ | ||
| public static final Bytes ZERO = fromByte((byte) 0); |
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.
Bug: Type Mismatch: ZERO Constant Threatens Integrity
The ZERO constant is declared as type Bytes instead of Bytes32, causing a type inconsistency. The javadoc states it's a Bytes32 containing all zero bytes, but the actual type doesn't match. This breaks type safety and could cause issues when code expects a Bytes32 instance but receives a generic Bytes reference.
| public static final int SIZE = 48; | ||
|
|
||
| /** A {@code Bytes48} containing all zero bytes */ | ||
| public static final Bytes ZERO = fromByte((byte) 0); |
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.
Bug: ZERO Constant: Type Inconsistency Threatens Safety
The ZERO constant is declared as type Bytes instead of Bytes48, causing a type inconsistency. The javadoc states it's a Bytes48 containing all zero bytes, but the actual type doesn't match. This breaks type safety and could cause issues when code expects a Bytes48 instance but receives a generic Bytes reference.
| byte[] newBytesArray = new byte[otherSize]; | ||
| System.arraycopy(bytesArray, 0, newBytesArray, otherSize - size, size); | ||
| bytesArray = newBytesArray; | ||
| size = otherSize; |
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.
Bug: Immutability Contract Violated: Stale Hashcodes
The and, or, and xor methods mutate the size field after object construction when resizing the internal array. Since size is inherited from the immutable parent Bytes class and used for hashcode caching, this mutation breaks the immutability contract and can cause cached hashcodes to become stale, leading to incorrect behavior in hash-based collections.
PR description
This PR simplifies the Tuweni class hierarchy of the
bytesproject and attempts to get some performance gains by reducing memory churn, specially for copying byte arrays and Bytes instances. Bytes have now a much flatter class hierarchy that will hopefully improve inlining and reduce time onitablelookups which was identified as one of the problems in Besu for low performance. The implementation ofBytesused at runtime is now highly biased towardsArrayWrappingByteswhich makes it easier for JIT to inline and optimize.Also mutable operations wil be moved into
MutableBytesexclusively to show intention in copies. This avoids copies on sequences of logic operations, e.g.MutableBytes.create(10).or(Bytes.fromHex("0x11")).shiftRight(2)no further copies occur after initial instance creation.Other
Bytessubtypes should be immutable from now on to boost performance.Note
Adds new v2 modules for DevP2P (incl. Discovery v5), RLP/SSZ encodings, IO/TLS utilities, and unsigned big-integer types with comprehensive tests.
Endpoint, ENR parsing/validation (EthereumNodeRecord), packet/message types, peers/repository/routing table, and a Vert.x-based Discovery v5 service with handshake, session encryption (AES-GCM/HKDF), and topic table.UInt32,UInt64,UInt256,UInt384with arithmetic/bit ops and tests.Written by Cursor Bugbot for commit ad67e19. This will update automatically on new commits. Configure here.