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. 15
      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.recipient = recipient;
this.value = value;
this.inputData = inputData;
this.inputData = inputData.copy();
this.outputData = outputData;
this.stack = stack;
this.memory = memory;

@ -34,6 +34,6 @@ public class IDPrecompiledContract extends AbstractPrecompiledContract {
@Override
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());
}
final Bytes inputData = frame.readMemory(inputDataOffset(frame), inputDataLength(frame));
final Bytes inputData =
frame.readMutableMemory(inputDataOffset(frame), inputDataLength(frame));
final MessageFrame childFrame =
MessageFrame.builder()

@ -15,10 +15,10 @@
package org.hyperledger.besu.ethereum.vm;
import java.math.BigInteger;
import java.util.Arrays;
import org.apache.tuweni.bytes.Bytes;
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.UInt256s;
@ -40,18 +40,18 @@ public class Memory {
* 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.
*/
private byte[] data;
private MutableBytes data;
private UInt256 activeWords;
private int dataSize256;
public Memory() {
data = new byte[0];
data = MutableBytes.EMPTY;
updateSize();
}
private void updateSize() {
dataSize256 = data.length / Bytes32.SIZE;
dataSize256 = data.size() / Bytes32.SIZE;
activeWords = UInt256.valueOf(dataSize256);
}
@ -170,8 +170,8 @@ public class Memory {
if (dataSize256 >= newActiveWords) return;
// Require full capacity to guarantee we don't resize more than once.
final byte[] newData = new byte[newActiveWords * Bytes32.SIZE];
System.arraycopy(data, 0, newData, 0, data.length);
final MutableBytes newData = MutableBytes.create(newActiveWords * Bytes32.SIZE);
data.copyTo(newData, 0);
data = newData;
updateSize();
}
@ -189,12 +189,12 @@ public class Memory {
if (!(other instanceof Memory)) return false;
final Memory that = (Memory) other;
return Arrays.equals(this.data, that.data);
return this.data.equals(that.data);
}
@Override
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.
*/
int getActiveBytes() {
return data.length;
return data.size();
}
/**
@ -236,7 +236,7 @@ public class Memory {
final int start = asByteIndex(location);
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);
if (srcLength >= length) {
System.arraycopy(taintedValue.toArrayUnsafe(), 0, data, start, length);
data.set(start, taintedValue.slice(0, length));
} else {
Arrays.fill(data, start, end, (byte) 0);
System.arraycopy(taintedValue.toArrayUnsafe(), 0, data, start, srcLength);
data.set(start, Bytes.of(new byte[end - start]));
data.set(start, taintedValue.slice(0, srcLength));
}
}
@ -337,7 +337,7 @@ public class Memory {
}
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) {
final int start = asByteIndex(location);
ensureCapacityForBytes(start, 1);
data[start] = value;
data.set(start, value);
}
/**
@ -361,7 +361,7 @@ public class Memory {
public Bytes32 getWord(final UInt256 location) {
final int start = asByteIndex(location);
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) {
final int start = asByteIndex(location);
ensureCapacityForBytes(start, Bytes32.SIZE);
System.arraycopy(bytes.toArrayUnsafe(), 0, data, start, Bytes32.SIZE);
data.set(start, bytes);
}
@Override
public String toString() {
return Bytes.wrap(data).toHexString();
return data.toHexString();
}
}

@ -562,6 +562,17 @@ public class MessageFrame {
this.revertReason = Optional.ofNullable(revertReason);
}
/**
* 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 .
*
@ -570,7 +581,7 @@ public class MessageFrame {
* @return The bytes in the specified range
*/
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
* @return The bytes in the specified range
*/
public Bytes readMemory(
public Bytes readMutableMemory(
final UInt256 offset, final UInt256 length, final boolean explicitMemoryRead) {
final Bytes value = memory.getBytes(offset, length);
if (explicitMemoryRead) {

@ -96,7 +96,7 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
private void fail(final MessageFrame frame) {
final UInt256 inputOffset = frame.getStackItem(1);
final UInt256 inputSize = frame.getStackItem(2);
frame.readMemory(inputOffset, inputSize);
frame.readMutableMemory(inputOffset, inputSize);
frame.popStackItems(getStackItemsConsumed());
frame.pushStackItem(UInt256.ZERO);
}
@ -114,7 +114,7 @@ public abstract class AbstractCreateOperation extends AbstractOperation {
final Wei value = Wei.wrap(frame.getStackItem(0));
final UInt256 inputOffset = frame.getStackItem(1);
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);

@ -38,7 +38,7 @@ public class Create2Operation extends AbstractCreateOperation {
final UInt256 offset = frame.getStackItem(1);
final UInt256 length = frame.getStackItem(2);
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 Address address = Address.extract(hash);
frame.warmUpAddress(address);

@ -43,7 +43,8 @@ public class MLoadOperation extends AbstractOperation {
}
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);
return new OperationResult(optionalCost, Optional.empty());

@ -44,7 +44,7 @@ public class Sha3Operation extends AbstractOperation {
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)));
return new OperationResult(optionalCost, Optional.empty());
}

Loading…
Cancel
Save