Update memory to use MutableBytes (#2673)

Signed-off-by: Karim TAAM <karim.t2am@gmail.com>
pull/2748/head
matkt 3 years ago committed by GitHub
parent e409e2cafb
commit 61ae7b0384
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/debug/TraceFrame.java
  2. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/precompiles/IDPrecompiledContract.java
  3. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/AbstractCallOperation.java
  4. 37
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/Memory.java
  5. 17
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/MessageFrame.java
  6. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/operations/AbstractCreateOperation.java
  7. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/operations/Create2Operation.java
  8. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/operations/MLoadOperation.java
  9. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/operations/Sha3Operation.java

@ -92,7 +92,7 @@ public class TraceFrame {
this.exceptionalHaltReason = exceptionalHaltReason; this.exceptionalHaltReason = exceptionalHaltReason;
this.recipient = recipient; this.recipient = recipient;
this.value = value; this.value = value;
this.inputData = inputData; this.inputData = inputData.copy();
this.outputData = outputData; this.outputData = outputData;
this.stack = stack; this.stack = stack;
this.memory = memory; this.memory = memory;

@ -34,6 +34,6 @@ public class IDPrecompiledContract extends AbstractPrecompiledContract {
@Override @Override
public Bytes compute(final Bytes input, final MessageFrame messageFrame) { public Bytes compute(final Bytes input, final MessageFrame messageFrame) {
return input; return input.copy();
} }
} }

@ -182,7 +182,8 @@ public abstract class AbstractCallOperation extends AbstractOperation {
return new OperationResult(optionalCost, Optional.empty()); return new OperationResult(optionalCost, Optional.empty());
} }
final Bytes inputData = frame.readMemory(inputDataOffset(frame), inputDataLength(frame)); final Bytes inputData =
frame.readMutableMemory(inputDataOffset(frame), inputDataLength(frame));
final MessageFrame childFrame = final MessageFrame childFrame =
MessageFrame.builder() MessageFrame.builder()

@ -15,10 +15,10 @@
package org.hyperledger.besu.ethereum.vm; package org.hyperledger.besu.ethereum.vm;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Arrays;
import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.bytes.MutableBytes;
import org.apache.tuweni.units.bigints.UInt256; import org.apache.tuweni.units.bigints.UInt256;
import org.apache.tuweni.units.bigints.UInt256s; import org.apache.tuweni.units.bigints.UInt256s;
@ -40,18 +40,18 @@ public class Memory {
* overflow this. A byte array implementation limits us to 2GiB. But that would cost over 51 * overflow this. A byte array implementation limits us to 2GiB. But that would cost over 51
* trillion gas. So this is likely a reasonable limitation, at least at first. * trillion gas. So this is likely a reasonable limitation, at least at first.
*/ */
private byte[] data; private MutableBytes data;
private UInt256 activeWords; private UInt256 activeWords;
private int dataSize256; private int dataSize256;
public Memory() { public Memory() {
data = new byte[0]; data = MutableBytes.EMPTY;
updateSize(); updateSize();
} }
private void updateSize() { private void updateSize() {
dataSize256 = data.length / Bytes32.SIZE; dataSize256 = data.size() / Bytes32.SIZE;
activeWords = UInt256.valueOf(dataSize256); activeWords = UInt256.valueOf(dataSize256);
} }
@ -170,8 +170,8 @@ public class Memory {
if (dataSize256 >= newActiveWords) return; if (dataSize256 >= newActiveWords) return;
// Require full capacity to guarantee we don't resize more than once. // Require full capacity to guarantee we don't resize more than once.
final byte[] newData = new byte[newActiveWords * Bytes32.SIZE]; final MutableBytes newData = MutableBytes.create(newActiveWords * Bytes32.SIZE);
System.arraycopy(data, 0, newData, 0, data.length); data.copyTo(newData, 0);
data = newData; data = newData;
updateSize(); updateSize();
} }
@ -189,12 +189,12 @@ public class Memory {
if (!(other instanceof Memory)) return false; if (!(other instanceof Memory)) return false;
final Memory that = (Memory) other; final Memory that = (Memory) other;
return Arrays.equals(this.data, that.data); return this.data.equals(that.data);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Arrays.hashCode(data); return data.hashCode();
} }
/** /**
@ -203,7 +203,7 @@ public class Memory {
* @return The current number of active bytes stored in memory. * @return The current number of active bytes stored in memory.
*/ */
int getActiveBytes() { int getActiveBytes() {
return data.length; return data.size();
} }
/** /**
@ -236,7 +236,7 @@ public class Memory {
final int start = asByteIndex(location); final int start = asByteIndex(location);
ensureCapacityForBytes(start, length); ensureCapacityForBytes(start, length);
return Bytes.of(Arrays.copyOfRange(data, start, start + numBytes.intValue())); return data.slice(start, numBytes.intValue());
} }
/** /**
@ -303,10 +303,10 @@ public class Memory {
ensureCapacityForBytes(start, length); ensureCapacityForBytes(start, length);
if (srcLength >= length) { if (srcLength >= length) {
System.arraycopy(taintedValue.toArrayUnsafe(), 0, data, start, length); data.set(start, taintedValue.slice(0, length));
} else { } else {
Arrays.fill(data, start, end, (byte) 0); data.set(start, Bytes.of(new byte[end - start]));
System.arraycopy(taintedValue.toArrayUnsafe(), 0, data, start, srcLength); data.set(start, taintedValue.slice(0, srcLength));
} }
} }
@ -337,7 +337,7 @@ public class Memory {
} }
ensureCapacityForBytes(location, numBytes); ensureCapacityForBytes(location, numBytes);
Arrays.fill(data, location, location + numBytes, (byte) 0); data.set(location, Bytes.of(new byte[numBytes]));
} }
/** /**
@ -349,7 +349,7 @@ public class Memory {
void setByte(final UInt256 location, final byte value) { void setByte(final UInt256 location, final byte value) {
final int start = asByteIndex(location); final int start = asByteIndex(location);
ensureCapacityForBytes(start, 1); ensureCapacityForBytes(start, 1);
data[start] = value; data.set(start, value);
} }
/** /**
@ -361,7 +361,7 @@ public class Memory {
public Bytes32 getWord(final UInt256 location) { public Bytes32 getWord(final UInt256 location) {
final int start = asByteIndex(location); final int start = asByteIndex(location);
ensureCapacityForBytes(start, Bytes32.SIZE); ensureCapacityForBytes(start, Bytes32.SIZE);
return Bytes32.wrap(Arrays.copyOfRange(data, start, start + Bytes32.SIZE)); return Bytes32.wrap(data.slice(start, Bytes32.SIZE));
} }
/** /**
@ -376,12 +376,11 @@ public class Memory {
public void setWord(final UInt256 location, final Bytes32 bytes) { public void setWord(final UInt256 location, final Bytes32 bytes) {
final int start = asByteIndex(location); final int start = asByteIndex(location);
ensureCapacityForBytes(start, Bytes32.SIZE); ensureCapacityForBytes(start, Bytes32.SIZE);
data.set(start, bytes);
System.arraycopy(bytes.toArrayUnsafe(), 0, data, start, Bytes32.SIZE);
} }
@Override @Override
public String toString() { public String toString() {
return Bytes.wrap(data).toHexString(); return data.toHexString();
} }
} }

@ -563,14 +563,25 @@ public class MessageFrame {
} }
/** /**
* Read bytes in memory. * Read bytes in memory as mutable.
*
* @param offset The offset in memory
* @param length The length of the bytes to read
* @return The bytes in the specified range
*/
public Bytes readMutableMemory(final UInt256 offset, final UInt256 length) {
return readMutableMemory(offset, length, false);
}
/**
* Read bytes in memory .
* *
* @param offset The offset in memory * @param offset The offset in memory
* @param length The length of the bytes to read * @param length The length of the bytes to read
* @return The bytes in the specified range * @return The bytes in the specified range
*/ */
public Bytes readMemory(final UInt256 offset, final UInt256 length) { public Bytes readMemory(final UInt256 offset, final UInt256 length) {
return readMemory(offset, length, false); return readMutableMemory(offset, length, false).copy();
} }
/** /**
@ -581,7 +592,7 @@ public class MessageFrame {
* @param explicitMemoryRead true if triggered by a memory opcode, false otherwise * @param explicitMemoryRead true if triggered by a memory opcode, false otherwise
* @return The bytes in the specified range * @return The bytes in the specified range
*/ */
public Bytes readMemory( public Bytes readMutableMemory(
final UInt256 offset, final UInt256 length, final boolean explicitMemoryRead) { final UInt256 offset, final UInt256 length, final boolean explicitMemoryRead) {
final Bytes value = memory.getBytes(offset, length); final Bytes value = memory.getBytes(offset, length);
if (explicitMemoryRead) { if (explicitMemoryRead) {

@ -96,7 +96,7 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
private void fail(final MessageFrame frame) { private void fail(final MessageFrame frame) {
final UInt256 inputOffset = frame.getStackItem(1); final UInt256 inputOffset = frame.getStackItem(1);
final UInt256 inputSize = frame.getStackItem(2); final UInt256 inputSize = frame.getStackItem(2);
frame.readMemory(inputOffset, inputSize); frame.readMutableMemory(inputOffset, inputSize);
frame.popStackItems(getStackItemsConsumed()); frame.popStackItems(getStackItemsConsumed());
frame.pushStackItem(UInt256.ZERO); frame.pushStackItem(UInt256.ZERO);
} }
@ -114,7 +114,7 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
final Wei value = Wei.wrap(frame.getStackItem(0)); final Wei value = Wei.wrap(frame.getStackItem(0));
final UInt256 inputOffset = frame.getStackItem(1); final UInt256 inputOffset = frame.getStackItem(1);
final UInt256 inputSize = frame.getStackItem(2); final UInt256 inputSize = frame.getStackItem(2);
final Bytes inputData = frame.readMemory(inputOffset, inputSize); final Bytes inputData = frame.readMutableMemory(inputOffset, inputSize);
final Address contractAddress = targetContractAddress(frame); final Address contractAddress = targetContractAddress(frame);

@ -38,7 +38,7 @@ public class Create2Operation extends AbstractCreateOperation {
final UInt256 offset = frame.getStackItem(1); final UInt256 offset = frame.getStackItem(1);
final UInt256 length = frame.getStackItem(2); final UInt256 length = frame.getStackItem(2);
final Bytes32 salt = frame.getStackItem(3); final Bytes32 salt = frame.getStackItem(3);
final Bytes initCode = frame.readMemory(offset, length); final Bytes initCode = frame.readMutableMemory(offset, length);
final Hash hash = Hash.hash(Bytes.concatenate(PREFIX, sender, salt, Hash.hash(initCode))); final Hash hash = Hash.hash(Bytes.concatenate(PREFIX, sender, salt, Hash.hash(initCode)));
final Address address = Address.extract(hash); final Address address = Address.extract(hash);
frame.warmUpAddress(address); frame.warmUpAddress(address);

@ -43,7 +43,8 @@ public class MLoadOperation extends AbstractOperation {
} }
final UInt256 value = final UInt256 value =
UInt256.fromBytes(Bytes32.leftPad(frame.readMemory(location, UInt256.valueOf(32), true))); UInt256.fromBytes(
Bytes32.leftPad(frame.readMutableMemory(location, UInt256.valueOf(32), true)));
frame.pushStackItem(value); frame.pushStackItem(value);
return new OperationResult(optionalCost, Optional.empty()); return new OperationResult(optionalCost, Optional.empty());

@ -44,7 +44,7 @@ public class Sha3Operation extends AbstractOperation {
return new OperationResult(optionalCost, Optional.of(ExceptionalHaltReason.INSUFFICIENT_GAS)); return new OperationResult(optionalCost, Optional.of(ExceptionalHaltReason.INSUFFICIENT_GAS));
} }
final Bytes bytes = frame.readMemory(from, length); final Bytes bytes = frame.readMutableMemory(from, length);
frame.pushStackItem(UInt256.fromBytes(Hash.hash(bytes))); frame.pushStackItem(UInt256.fromBytes(Hash.hash(bytes)));
return new OperationResult(optionalCost, Optional.empty()); return new OperationResult(optionalCost, Optional.empty());
} }

Loading…
Cancel
Save