Skip to content
This repository has been archived by the owner on Dec 5, 2024. It is now read-only.

Feature/eip 145 #1167

Merged
merged 6 commits into from
Aug 24, 2018
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ String validateTransactionChanges(BlockStore blockStore, Block curBlock, Transac
*/
boolean eip658();

/**
* EIP145: https://eips.ethereum.org/EIPS/eip-145
* Bitwise shifting instructions in EVM
*/
boolean eip145();

/**
* EIP1052: https://eips.ethereum.org/EIPS/eip-1052
* EXTCODEHASH opcode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ public boolean eip1052() {
return false;
}

@Override
public boolean eip145() {
return false;
}

@Override
public String toString() {
return getClass().getSimpleName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,9 @@ public ConstantinopleConfig(BlockchainConfig parent) {
public boolean eip1052() {
return true;
}

@Override
public boolean eip145() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ public boolean eip658() {
return false;
}

@Override
public boolean eip145() {
return false;
}

@Override
public boolean eip1052() {
return false;
Expand Down
62 changes: 49 additions & 13 deletions ethereumj-core/src/main/java/org/ethereum/vm/DataWord.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@
public final class DataWord implements Comparable<DataWord> {

/* Maximum value of the DataWord */
public static final BigInteger _2_256 = BigInteger.valueOf(2).pow(256);
public static final int MAX_POW = 256;
public static final BigInteger _2_256 = BigInteger.valueOf(2).pow(MAX_POW);
public static final BigInteger MAX_VALUE = _2_256.subtract(BigInteger.ONE);
public static final DataWord ZERO = new DataWord(new byte[32]);
public static final DataWord ONE = DataWord.of((byte) 1);
Expand Down Expand Up @@ -249,19 +250,8 @@ public DataWord xor(DataWord word) {
}

public DataWord negate() {

if (this.isZero()) return ZERO;

byte[] newData = this.copyData();
for (int i = 0; i < this.data.length; ++i) {
newData[i] = (byte) ~this.data[i];
}

for (int i = this.data.length - 1; i >= 0; --i) {
newData[i] = (byte) (1 + this.data[i] & 0xFF);
if (newData[i] != 0) break;
}
return new DataWord(newData);
return bnot().add(DataWord.ONE);
}

public DataWord bnot() {
Expand Down Expand Up @@ -373,6 +363,52 @@ public DataWord mulmod(DataWord word1, DataWord word2) {
return new DataWord(ByteUtil.copyToArray(result.and(MAX_VALUE)));
}

/**
* Shift left, both this and input arg are treated as unsigned
* @param arg
* @return this << arg
*/
public DataWord shiftLeft(DataWord arg) {
if (arg.value().compareTo(BigInteger.valueOf(MAX_POW)) >= 0) {
return DataWord.ZERO;
}

BigInteger result = value().shiftLeft(arg.intValueSafe());
return new DataWord(ByteUtil.copyToArray(result.and(MAX_VALUE)));
}

/**
* Shift right, both this and input arg are treated as unsigned
* @param arg
* @return this >> arg
*/
public DataWord shiftRight(DataWord arg) {
if (arg.value().compareTo(BigInteger.valueOf(MAX_POW)) >= 0) {
return DataWord.ZERO;
}

BigInteger result = value().shiftRight(arg.intValueSafe());
return new DataWord(ByteUtil.copyToArray(result.and(MAX_VALUE)));
}

/**
* Shift right, this is signed, while input arg is treated as unsigned
* @param arg
* @return this >> arg
*/
public DataWord shiftRightSigned(DataWord arg) {
if (arg.value().compareTo(BigInteger.valueOf(MAX_POW)) >= 0) {
if (this.isNegative()) {
return DataWord.ONE.negate();
} else {
return DataWord.ZERO;
}
}

BigInteger result = sValue().shiftRight(arg.intValueSafe());
return new DataWord(ByteUtil.copyToArray(result.and(MAX_VALUE)));
}

@JsonValue
@Override
public String toString() {
Expand Down
12 changes: 12 additions & 0 deletions ethereumj-core/src/main/java/org/ethereum/vm/OpCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,18 @@ public enum OpCode {
* (0x1a) Retrieve single byte from word
*/
BYTE(0x1a, 2, 1, VeryLowTier),
/**
* (0x1b) Shift left
*/
SHL(0x1b, 2, 1, VeryLowTier),
/**
* (0x1c) Logical shift right
*/
SHR(0x1c, 2, 1, VeryLowTier),
/**
* (0x1d) Arithmetic shift right
*/
SAR(0x1d, 2, 1, VeryLowTier),

/* Cryptographic Operations */

Expand Down
39 changes: 39 additions & 0 deletions ethereumj-core/src/main/java/org/ethereum/vm/VM.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ public class VM {
put(RETURNDATASIZE, BlockchainConfig::eip211);
put(STATICCALL, BlockchainConfig::eip214);
put(EXTCODEHASH, BlockchainConfig::eip1052);
put(SHL, BlockchainConfig::eip145);
put(SHR, BlockchainConfig::eip145);
put(SAR, BlockchainConfig::eip145);
}};

private final SystemProperties config;
Expand Down Expand Up @@ -671,6 +674,42 @@ else if (oldValue != null && newValue.isZero()) {
program.step();
}
break;
case SHL: {
DataWord word1 = program.stackPop();
DataWord word2 = program.stackPop();
final DataWord result = word2.shiftLeft(word1);

if (logger.isInfoEnabled())
hint = "" + result.value();

program.stackPush(result);
program.step();
}
break;
case SHR: {
DataWord word1 = program.stackPop();
DataWord word2 = program.stackPop();
final DataWord result = word2.shiftRight(word1);

if (logger.isInfoEnabled())
hint = "" + result.value();

program.stackPush(result);
program.step();
}
break;
case SAR: {
DataWord word1 = program.stackPop();
DataWord word2 = program.stackPop();
final DataWord result = word2.shiftRightSigned(word1);

if (logger.isInfoEnabled())
hint = "" + result.value();

program.stackPush(result);
program.step();
}
break;
case ADDMOD: {
DataWord word1 = program.stackPop();
DataWord word2 = program.stackPop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ public class Program {
private final BlockchainConfig blockchainConfig;

public Program(byte[] ops, ProgramInvoke programInvoke) {
this(ops, programInvoke, null);
this(ops, programInvoke, (Transaction) null);
}

public Program(byte[] ops, ProgramInvoke programInvoke, SystemProperties config) {
this(ops, programInvoke, null, config);
}

public Program(byte[] ops, ProgramInvoke programInvoke, Transaction transaction) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,4 +318,14 @@ public void stExtCodeHashCall() throws IOException {
BlockchainTestSuite.runSingle(filePath, commit, GitHubJSONTestSuite.Network.Constantinople);
BlockchainTestSuite.runSingle(filePath, commit, GitHubJSONTestSuite.Network.Byzantium);
}

@Test
@Ignore("Update after all tests could pass latest develop")
public void stShiftTest() throws IOException {
suite.runAll("stShift");
// TODO: Update all, this one passes with following settings:
// String commitSHA = "560e2cd6cf881821180d46d9cc4c542e19cfea1d";
// String treeSHA = "8457a6a49f53218575a349abc311c55939797bff";
// targetNets += GitHubJSONTestSuite.Network.Constantinople
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -320,5 +320,15 @@ public void stExtCodeHashCall() throws IOException {
GeneralStateTestSuite.runSingle(filePath, commit, GitHubJSONTestSuite.Network.Constantinople);
GeneralStateTestSuite.runSingle(filePath, commit, GitHubJSONTestSuite.Network.Byzantium);
}

@Test
@Ignore("Update after all tests could pass latest develop")
public void stShiftTest() throws IOException {
suite.runAll("stShift");
// TODO: Update all, this one passes with following settings:
// String commit = "ad2184adca367c0b68c65b44519dba16e1d0b9e2";
// String treeSha = "4dd59a4f448dc06c3641bd5cb9c35cf6a099e438";
// targetNets += GitHubJSONTestSuite.Network.Constantinople
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public static List<String> validRoot(String currRoot, String postRoot) {
List<String> results = new ArrayList<>();
if (!postRoot.equals(currRoot)){

String formattedString = String.format("Root hash don't much: expected: %s current: %s",
String formattedString = String.format("Root hash doesn't match: expected: %s current: %s",
postRoot, currRoot);
results.add(formattedString);
}
Expand Down
Loading