Remove unnecessary RlpInput and RlpOutput classes (#287)

mbaxter 6 years ago committed by GitHub
parent 6125451acf
commit ec1a8be558
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      ethereum/p2p/src/main/java/tech/pegasys/pantheon/ethereum/p2p/discovery/internal/Packet.java
  2. 25
      ethereum/rlp/src/main/java/tech/pegasys/pantheon/ethereum/rlp/AbstractRLPOutput.java
  3. 7
      ethereum/rlp/src/main/java/tech/pegasys/pantheon/ethereum/rlp/BytesValueRLPInput.java
  4. 107
      ethereum/rlp/src/main/java/tech/pegasys/pantheon/ethereum/rlp/FileRLPInput.java
  5. 4
      ethereum/rlp/src/main/java/tech/pegasys/pantheon/ethereum/rlp/RLP.java
  6. 96
      ethereum/rlp/src/main/java/tech/pegasys/pantheon/ethereum/rlp/VertxBufferRLPInput.java
  7. 40
      ethereum/rlp/src/main/java/tech/pegasys/pantheon/ethereum/rlp/VertxBufferRLPOutput.java
  8. 15
      util/src/main/java/tech/pegasys/pantheon/util/bytes/BytesValue.java

@ -21,9 +21,9 @@ import tech.pegasys.pantheon.crypto.SECP256K1;
import tech.pegasys.pantheon.crypto.SECP256K1.PublicKey; import tech.pegasys.pantheon.crypto.SECP256K1.PublicKey;
import tech.pegasys.pantheon.crypto.SECP256K1.Signature; import tech.pegasys.pantheon.crypto.SECP256K1.Signature;
import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryPacketDecodingException; import tech.pegasys.pantheon.ethereum.p2p.discovery.PeerDiscoveryPacketDecodingException;
import tech.pegasys.pantheon.ethereum.rlp.BytesValueRLPOutput;
import tech.pegasys.pantheon.ethereum.rlp.RLP; import tech.pegasys.pantheon.ethereum.rlp.RLP;
import tech.pegasys.pantheon.ethereum.rlp.RLPException; import tech.pegasys.pantheon.ethereum.rlp.RLPException;
import tech.pegasys.pantheon.ethereum.rlp.VertxBufferRLPOutput;
import tech.pegasys.pantheon.util.bytes.BytesValue; import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.bytes.MutableBytesValue; import tech.pegasys.pantheon.util.bytes.MutableBytesValue;
import tech.pegasys.pantheon.util.uint.UInt256Bytes; import tech.pegasys.pantheon.util.uint.UInt256Bytes;
@ -122,7 +122,7 @@ public class Packet {
public Buffer encode() { public Buffer encode() {
final BytesValue encodedSignature = encodeSignature(signature); final BytesValue encodedSignature = encodeSignature(signature);
final VertxBufferRLPOutput encodedData = new VertxBufferRLPOutput(); final BytesValueRLPOutput encodedData = new BytesValueRLPOutput();
data.writeTo(encodedData); data.writeTo(encodedData);
final Buffer buffer = final Buffer buffer =
@ -130,10 +130,23 @@ public class Packet {
hash.appendTo(buffer); hash.appendTo(buffer);
encodedSignature.appendTo(buffer); encodedSignature.appendTo(buffer);
buffer.appendByte(type.getValue()); buffer.appendByte(type.getValue());
encodedData.appendEncoded(buffer); appendEncoded(encodedData, buffer);
return buffer; return buffer;
} }
protected void appendEncoded(final BytesValueRLPOutput encoded, final Buffer buffer) {
final int size = encoded.encodedSize();
if (size == 0) {
return;
}
// We want to append to the buffer, and Buffer always grows to accommodate anything writing,
// so we write the last byte we know we'll need to make it resize accordingly.
final int start = buffer.length();
buffer.setByte(start + size - 1, (byte) 0);
encoded.writeEncoded(MutableBytesValue.wrapBuffer(buffer, start, size));
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends PacketData> Optional<T> getPacketData(final Class<T> expectedPacketType) { public <T extends PacketData> Optional<T> getPacketData(final Class<T> expectedPacketType) {
if (data == null || !data.getClass().equals(expectedPacketType)) { if (data == null || !data.getClass().equals(expectedPacketType)) {

@ -141,7 +141,12 @@ abstract class AbstractRLPOutput implements RLPOutput {
return payloadSizes[0]; return payloadSizes[0];
} }
protected void writeEncoded(final MutableBytesValue res) { /**
* Write the rlp encoded value to the provided {@link MutableBytesValue}
*
* @param mutableBytesValue the value to which the rlp-data will be written
*/
public void writeEncoded(final MutableBytesValue mutableBytesValue) {
// Special case where we encode only a single non-list item (note that listsCount is initially // Special case where we encode only a single non-list item (note that listsCount is initially
// set to 1, so listsCount == 1 really mean no list explicitly added to the output). // set to 1, so listsCount == 1 really mean no list explicitly added to the output).
if (listsCount == 1) { if (listsCount == 1) {
@ -152,15 +157,15 @@ abstract class AbstractRLPOutput implements RLPOutput {
final int finalOffset; final int finalOffset;
// Single non-list value. // Single non-list value.
if (rlpEncoded.get(0)) { if (rlpEncoded.get(0)) {
value.copyTo(res, 0); value.copyTo(mutableBytesValue, 0);
finalOffset = value.size(); finalOffset = value.size();
} else { } else {
finalOffset = writeElement(value, res, 0); finalOffset = writeElement(value, mutableBytesValue, 0);
} }
checkState( checkState(
finalOffset == res.size(), finalOffset == mutableBytesValue.size(),
"Expected single element RLP encode to be of size %s but was of size %s.", "Expected single element RLP encode to be of size %s but was of size %s.",
res.size(), mutableBytesValue.size(),
finalOffset); finalOffset);
return; return;
} }
@ -171,19 +176,19 @@ abstract class AbstractRLPOutput implements RLPOutput {
final BytesValue value = values.get(i); final BytesValue value = values.get(i);
if (value == LIST_MARKER) { if (value == LIST_MARKER) {
final int payloadSize = payloadSizes[++listIdx]; final int payloadSize = payloadSizes[++listIdx];
offset = writeListHeader(payloadSize, res, offset); offset = writeListHeader(payloadSize, mutableBytesValue, offset);
} else if (rlpEncoded.get(i)) { } else if (rlpEncoded.get(i)) {
value.copyTo(res, offset); value.copyTo(mutableBytesValue, offset);
offset += value.size(); offset += value.size();
} else { } else {
offset = writeElement(value, res, offset); offset = writeElement(value, mutableBytesValue, offset);
} }
} }
checkState( checkState(
offset == res.size(), offset == mutableBytesValue.size(),
"Expected RLP encoding to be of size %s but was of size %s.", "Expected RLP encoding to be of size %s but was of size %s.",
res.size(), mutableBytesValue.size(),
offset); offset);
} }
} }

@ -25,9 +25,14 @@ public class BytesValueRLPInput extends AbstractRLPInput {
private final BytesValue value; private final BytesValue value;
public BytesValueRLPInput(final BytesValue value, final boolean lenient) { public BytesValueRLPInput(final BytesValue value, final boolean lenient) {
this(value, lenient, true);
}
public BytesValueRLPInput(
final BytesValue value, final boolean lenient, final boolean shouldFitExactly) {
super(lenient); super(lenient);
this.value = value; this.value = value;
init(value.size(), true); init(value.size(), shouldFitExactly);
} }
@Override @Override

@ -1,107 +0,0 @@
/*
* Copyright 2018 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.ethereum.rlp;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import tech.pegasys.pantheon.util.bytes.Bytes32;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.bytes.BytesValues;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/** An {@link RLPInput} that reads RLP encoded data from a {@link File}. */
public class FileRLPInput extends AbstractRLPInput {
// The RLP encoded data.
private final FileChannel file;
public FileRLPInput(final FileChannel file, final boolean lenient) throws IOException {
super(lenient);
checkNotNull(file);
checkArgument(file.isOpen());
this.file = file;
init(file.size(), false);
}
@Override
protected byte inputByte(final long offset) {
try {
final ByteBuffer buf = ByteBuffer.wrap(new byte[1]);
file.read(buf, offset);
final byte b = buf.get(0);
return b;
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected BytesValue inputSlice(final long offset, final int length) {
try {
final byte[] bytes = new byte[length];
final ByteBuffer buf = ByteBuffer.wrap(bytes);
file.read(buf, offset);
return BytesValue.of(bytes);
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected Bytes32 inputSlice32(final long offset) {
return Bytes32.wrap(inputSlice(offset, 32), 0);
}
@Override
protected String inputHex(final long offset, final int length) {
return inputSlice(offset, length).toString().substring(2);
}
@Override
protected BigInteger getUnsignedBigInteger(final long offset, final int length) {
return BytesValues.asUnsignedBigInteger(inputSlice(offset, length));
}
@Override
protected int getInt(final long offset) {
return inputSlice(offset, Integer.BYTES).getInt(0);
}
@Override
protected long getLong(final long offset) {
return inputSlice(offset, Long.BYTES).getLong(0);
}
@Override
public BytesValue raw() {
throw new UnsupportedOperationException("raw() not supported on a Channel");
}
/** @return Offset of the current item */
public long currentOffset() {
return currentItem;
}
@Override
public void setTo(final long item) {
super.setTo(item);
}
}

@ -77,8 +77,8 @@ public abstract class RLP {
* deeply nested corruption/malformation of the input will not be detected by this method * deeply nested corruption/malformation of the input will not be detected by this method
* call, but only later when the input is read. * call, but only later when the input is read.
*/ */
public static VertxBufferRLPInput input(final Buffer buffer, final int offset) { public static BytesValueRLPInput input(final Buffer buffer, final int offset) {
return new VertxBufferRLPInput(buffer, offset, false); return new BytesValueRLPInput(BytesValue.wrapBuffer(buffer, offset), false, false);
} }
/** /**

@ -1,96 +0,0 @@
/*
* Copyright 2018 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.ethereum.rlp;
import tech.pegasys.pantheon.util.bytes.Bytes32;
import tech.pegasys.pantheon.util.bytes.BytesValue;
import tech.pegasys.pantheon.util.bytes.BytesValues;
import java.math.BigInteger;
import io.vertx.core.buffer.Buffer;
/** A {@link RLPInput} that decode RLP encoded data stored in a Vert.x {@link Buffer}. */
public class VertxBufferRLPInput extends AbstractRLPInput {
// The RLP encoded data.
private final Buffer buffer;
// Offset in buffer from which to read.
private final int bufferOffset;
/**
* A new {@link RLPInput} that decodes data from the provided buffer.
*
* @param buffer The buffer from which to read RLP data.
* @param bufferOffset The offset in {@code buffer} in which the data to decode starts.
* @param lenient Whether the created decoded should be lenient, that is ignore non-fatal
* malformation in the input.
*/
public VertxBufferRLPInput(final Buffer buffer, final int bufferOffset, final boolean lenient) {
super(lenient);
this.buffer = buffer;
this.bufferOffset = bufferOffset;
init(buffer.length(), false);
}
/**
* The total size of the encoded data in the {@link Buffer} wrapped by this object.
*
* @return The total size of the encoded data that this input decodes (note that this value never
* changes, it is not the size of data remaining to decode, but the size to decode at creation
* time).
*/
public int encodedSize() {
return Math.toIntExact(size);
}
@Override
protected byte inputByte(final long offset) {
return buffer.getByte(Math.toIntExact(bufferOffset + offset));
}
@Override
protected BytesValue inputSlice(final long offset, final int length) {
return BytesValue.wrapBuffer(buffer, Math.toIntExact(bufferOffset + offset), length);
}
@Override
protected Bytes32 inputSlice32(final long offset) {
return Bytes32.wrap(inputSlice(offset, Bytes32.SIZE), 0);
}
@Override
protected String inputHex(final long offset, final int length) {
return inputSlice(offset, length).toString().substring(2);
}
@Override
protected BigInteger getUnsignedBigInteger(final long offset, final int length) {
return BytesValues.asUnsignedBigInteger(inputSlice(offset, length));
}
@Override
protected int getInt(final long offset) {
return buffer.getInt(Math.toIntExact(bufferOffset + offset));
}
@Override
protected long getLong(final long offset) {
return buffer.getLong(Math.toIntExact(bufferOffset + offset));
}
@Override
public BytesValue raw() {
return BytesValue.wrap(buffer.getBytes());
}
}

@ -1,40 +0,0 @@
/*
* Copyright 2018 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.ethereum.rlp;
import tech.pegasys.pantheon.util.bytes.MutableBytesValue;
import io.vertx.core.buffer.Buffer;
/**
* A {@link RLPOutput} that writes/appends the result of RLP encoding to a Vert.x {@link Buffer}.
*/
public class VertxBufferRLPOutput extends AbstractRLPOutput {
/**
* Appends the RLP-encoded data written to this output to the provided Vert.x {@link Buffer}.
*
* @param buffer The buffer to which to append the data to.
*/
public void appendEncoded(final Buffer buffer) {
final int size = encodedSize();
if (size == 0) {
return;
}
// We want to append to the buffer, and Buffer always grows to accommodate anything writing,
// so we write the last byte we know we'll need to make it resize accordingly.
final int start = buffer.length();
buffer.setByte(start + size - 1, (byte) 0);
writeEncoded(MutableBytesValue.wrapBuffer(buffer, start, size));
}
}

@ -139,6 +139,21 @@ public interface BytesValue extends Comparable<BytesValue> {
return wrapBuffer(buffer, 0, buffer.length()); return wrapBuffer(buffer, 0, buffer.length());
} }
/**
* Wraps a full Vert.x {@link Buffer} as a {@link BytesValue}.
*
* <p>Note that as the buffer is wrapped, any change to the content of that buffer may be
* reflected in the returned value.
*
* @param buffer The buffer to wrap.
* @param offset The offset in {@code buffer} from which to expose the bytes in the returned
* value. That is, {@code wrapBuffer(buffer, i, 1).get(0) == buffer.getByte(i)}.
* @return A {@link BytesValue} that exposes the bytes of {@code buffer}.
*/
static BytesValue wrapBuffer(final Buffer buffer, final int offset) {
return wrapBuffer(buffer, offset, buffer.length() - offset);
}
/** /**
* Wraps a slice of a Vert.x {@link Buffer} as a {@link BytesValue}. * Wraps a slice of a Vert.x {@link Buffer} as a {@link BytesValue}.
* *

Loading…
Cancel
Save