Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

[NC-1561] Remove RLPUtils from RawBlockIterator #143

Closed

Conversation

mbaxter
Copy link
Contributor

@mbaxter mbaxter commented Oct 24, 2018

PR description

This PR removes RLPUtils from RawBlockIterator, as part of the work to removing RLPUtils altogether.

In order to remove this utility, I added a BytesValue class that wraps around java.nio.ByteBuffer. The purpose of the BytesValue abstraction is to allow our apis to work generically across various types that represent byte strings, so I felt that it was worth expanding the library to support this common type. Adding another BytesValue wrapper is pretty straightforward. However, the tests were not set up to run across the various BytesValue implementations. So, I spent some time refactoring the tests to get better coverage across the different implementations as well as standardizing some behavior across implementations.

In order to support the functionality that was previously provided by RLPUtils, I also had to refactor the rlp library to extract some functionality from AbstractRLPInput so that it could be used in a static helper method in RLP.

I added tests for RawBlockIterator and additional test coverage for the areas of the rlp functionality that were refactored.

Create BytesValue backed by ByteBuffer, extract some functionality from
RLPInput into static helper methods.
Standardize behavior across implementations.  Fix bug in ByteBuffer
wrapping BytesValue (byte access should include offset).
@smatthewenglish
Copy link
Contributor

this looks good to me. kind of a tangent but it reminded me of the Bytes32s class which always seemed to me kind of redundant along side BytesValue , but is it actually redundant?

@@ -32,7 +32,7 @@ public BytesValueRLPInput(final BytesValue value, final boolean lenient) {

@Override
protected byte inputByte(final long offset) {
return value.get(Math.toIntExact(offset));
return value.get(offset);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is required in the case of an input larger than Integer.MAX_VALUE. For example, Importing the blockchain with a 160GB file. The Interface needs to support the long offset. However, the bytes lib doesn't support long offsets.
Without this check, the long will be silently cast to an int, causing corrupted data in this implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a get() method to the BytesValue interface that accepts a long: https://github.com/PegaSysEng/pantheon/pull/143/files#diff-07c80cee998cbce23f1072fbe5c729f1R334

import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.function.Function;

public final class RawBlockIterator implements Iterator<Block>, Closeable {
private static final int DEFAULT_INIT_BUFFER_CAPACITY = 2 << 15;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional style: would 1 << 16 or 0x100 be more clear?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I thought this format was pretty weird, but just moved the value around. Will update.

@@ -31,7 +32,7 @@

private final boolean lenient;

protected long size;
protected long size; // The number of bytes in this rlp-encoded byte string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional style: a javadoc comment would turn up un API docs.

assertLongScalar(-1L, h("0xFFFFFFFFFFFFFFFF"));
BytesValue bytes = h("0x88FFFFFFFFFFFFFFFF");
final RLPInput in = RLP.input(bytes);
assertThatThrownBy(in::readLongScalar)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new formulation would read:

assertThatExceptionOfType(RLPException.class)
.isThrownBy(in::readLongScalar)
.withMessageStartingWith("long scalar -1 is not non-negative");

BytesValue bytes = h("0xB901");
assertThatThrownBy(() -> RLP.input(bytes))
.isInstanceOf(RLPException.class)
.hasRootCauseInstanceOf(CorruptedRLPInputException.class)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

withRootCauseInstanceOf in the new API.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants