diff --git a/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/CodeValidationSubCommandTest.java b/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/CodeValidationSubCommandTest.java index 3a17791a12..8d83a3c32a 100644 --- a/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/CodeValidationSubCommandTest.java +++ b/ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/CodeValidationSubCommandTest.java @@ -27,15 +27,16 @@ import picocli.CommandLine; public class CodeValidationSubCommandTest { static final String CODE_STOP_ONLY = "0xef0001 010004 020001-0001 030000 00 00000000 00"; - static final String CODE_RETF_ONLY = "0xef0001 010004 020001-0001 030000 00 00000000 b1"; - static final String CODE_BAD_MAGIC = "0xefffff 010004 020001-0001 030000 00 00000000 b1"; + static final String CODE_RETF_ONLY = "0xef0001 010004 020001-0001 030000 00 00000000 e4"; + static final String CODE_BAD_MAGIC = "0xefffff 010004 020001-0001 030000 00 00000000 e4"; static final String CODE_INTERIOR_COMMENTS = - "0xef0001 010008 020002-000c-0002 030000 00 \n" - + "# 7 inputs 1 output,\n" - + "00000007-07010007 \n" - + "59-59-59-59-59-59-59-b00001-50-b1\n" - + "# No immediate data\n" - + "f1-b1"; + """ + 0xef0001 010008 020002-000c-0002 030000 00 + # 7 inputs 1 output, + 00000007-07010007 + 59-59-59-59-59-59-59-e30001-50-e4 + # No immediate data + f1-e4"""; static final String CODE_MULTIPLE = CODE_STOP_ONLY + "\n" + CODE_BAD_MAGIC + "\n" + CODE_RETF_ONLY + "\n"; @@ -67,7 +68,12 @@ public class CodeValidationSubCommandTest { new CodeValidateSubCommand(bais, new PrintStream(baos)); codeValidateSubCommand.run(); assertThat(baos.toString(UTF_8)) - .contains("OK 00\n" + "err: layout - EOF header byte 1 incorrect\n" + "OK b1\n"); + .contains( + """ + OK 00 + err: layout - EOF header byte 1 incorrect + OK e4 + """); } @Test @@ -104,7 +110,12 @@ public class CodeValidationSubCommandTest { cmd.parseArgs(CODE_STOP_ONLY, CODE_BAD_MAGIC, CODE_RETF_ONLY); codeValidateSubCommand.run(); assertThat(baos.toString(UTF_8)) - .contains("OK 00\n" + "err: layout - EOF header byte 1 incorrect\n" + "OK b1\n"); + .contains( + """ + OK 00 + err: layout - EOF header byte 1 incorrect + OK e4 + """); } @Test @@ -116,7 +127,7 @@ public class CodeValidationSubCommandTest { final CommandLine cmd = new CommandLine(codeValidateSubCommand); cmd.parseArgs(CODE_RETF_ONLY); codeValidateSubCommand.run(); - assertThat(baos.toString(UTF_8)).contains("OK b1\n"); + assertThat(baos.toString(UTF_8)).contains("OK e4\n"); } @Test @@ -128,7 +139,7 @@ public class CodeValidationSubCommandTest { final CommandLine cmd = new CommandLine(codeValidateSubCommand); cmd.parseArgs(CODE_INTERIOR_COMMENTS); codeValidateSubCommand.run(); - assertThat(baos.toString(UTF_8)).contains("OK 59595959595959b0000150b1,f1b1\n"); + assertThat(baos.toString(UTF_8)).contains("OK 59595959595959e3000150e4,f1e4\n"); } @Test @@ -140,6 +151,11 @@ public class CodeValidationSubCommandTest { new CodeValidateSubCommand(bais, new PrintStream(baos)); codeValidateSubCommand.run(); assertThat(baos.toString(UTF_8)) - .isEqualTo("OK 00\n" + "err: layout - EOF header byte 1 incorrect\n" + "OK b1\n"); + .isEqualTo( + """ + OK 00 + err: layout - EOF header byte 1 incorrect + OK e4 + """); } } diff --git a/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1Validation.java b/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1Validation.java index 29663ae557..6174a2734a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1Validation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/code/CodeV1Validation.java @@ -135,9 +135,9 @@ public final class CodeV1Validation { VALID, // 0x59 - MSIZE VALID, // 0x5a - GAS VALID, // 0x5b - NOOOP (née JUMPDEST) - VALID_AND_TERMINAL, // 0X5c - RJUMP - VALID, // 0X5d - RJUMPI - VALID, // 0X5e - RJUMPV + VALID, // 0X5c - TLOAD + VALID, // 0X5d - TSTORE + VALID, // 0X5e - MCOPY VALID, // 0X5f - PUSH0 VALID, // 0x60 - PUSH1 VALID, // 0x61 - PUSH2 @@ -219,9 +219,9 @@ public final class CodeV1Validation { INVALID, // 0xad INVALID, // 0xae INVALID, // 0xaf - VALID, // 0xb0 - CALLF - VALID_AND_TERMINAL, // 0xb1 - RETF - INVALID, // 0xb2 - JUMPF + INVALID, // 0xb0 + INVALID, // 0xb1 + INVALID, // 0xb2 INVALID, // 0xb3 INVALID, // 0xb4 INVALID, // 0xb5 @@ -267,11 +267,11 @@ public final class CodeV1Validation { INVALID, // 0xdd INVALID, // 0xde INVALID, // 0xef - INVALID, // 0xe0 - INVALID, // 0xe1 - INVALID, // 0xe2 - INVALID, // 0xe3 - INVALID, // 0xe4 + VALID_AND_TERMINAL, // 0xe0 - RJUMP + VALID, // 0xe1 - RJUMPI + VALID, // 0xe2 - RJUMPV + VALID, // 0xe3 - CALLF + VALID_AND_TERMINAL, // 0xe4 - RETF INVALID, // 0xe5 INVALID, // 0xe6 INVALID, // 0xe7 @@ -398,9 +398,9 @@ public final class CodeV1Validation { {0, 1, 1}, // 0x59 - MSIZE {0, 1, 1}, // 0x5a - GAS {0, 0, 1}, // 0x5b - NOOP (née JUMPDEST) - {0, 0, -3}, // 0x5c - RJUMP - {1, 0, 3}, // 0x5d - RJUMPI - {1, 0, 2}, // 0x5e - RJUMPV + {1, 1, 1}, // 0x5c - TLOAD + {2, 0, 1}, // 0x5d - TSTORE + {4, 0, 1}, // 0x5e - MCOPY {0, 1, 1}, // 0x5f - PUSH0 {0, 1, 2}, // 0x60 - PUSH1 {0, 1, 3}, // 0x61 - PUSH2 @@ -482,9 +482,9 @@ public final class CodeV1Validation { {0, 0, 0}, // 0xad {0, 0, 0}, // 0xae {0, 0, 0}, // 0xaf - {0, 0, 3}, // 0xb0 - CALLF - {0, 0, -1}, // 0xb1 - RETF - {0, 0, 0}, // 0xb2 - JUMPF + {0, 0, 0}, // 0xb0 + {0, 0, 0}, // 0xb1 + {0, 0, 0}, // 0xb2 {0, 0, 0}, // 0xb3 {0, 0, 0}, // 0xb4 {0, 0, 0}, // 0xb5 @@ -530,12 +530,12 @@ public final class CodeV1Validation { {0, 0, 0}, // 0xdd {0, 0, 0}, // 0xde {0, 0, 0}, // 0xef - {0, 0, 0}, // 0xe0 - {0, 0, 0}, // 0xe1 - {0, 0, 0}, // 0xe2 - {0, 0, 0}, // 0xe3 - {0, 0, 0}, // 0xe4 - {0, 0, 0}, // 0xe5 + {0, 0, -3}, // 0xe0 - RJUMP + {1, 0, 3}, // 0xe1 - RJUMPI + {1, 0, 2}, // 0xe2 - RJUMPV + {0, 0, 3}, // 0xe3 - CALLF + {0, 0, -1}, // 0xe4 - RETF + {0, 0, 0}, // 0xe5 - JUMPF {0, 0, 0}, // 0xe6 {0, 0, 0}, // 0xe7 {0, 0, 0}, // 0xe8 diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallFOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallFOperation.java index 19688c0703..998d8a2e92 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/CallFOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/CallFOperation.java @@ -24,7 +24,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class CallFOperation extends AbstractOperation { /** The constant OPCODE. */ - public static final int OPCODE = 0xb0; + public static final int OPCODE = 0xe3; /** The Call F success. */ static final OperationResult callfSuccess = new OperationResult(5, null); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpFOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpFOperation.java index b647a8e8f1..612d70fb16 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpFOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/JumpFOperation.java @@ -24,7 +24,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class JumpFOperation extends AbstractOperation { /** The constant OPCODE. */ - public static final int OPCODE = 0xb2; + public static final int OPCODE = 0xe5; /** The Jump F success operation result. */ static final OperationResult jumpfSuccess = new OperationResult(3, null); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpIfOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpIfOperation.java index 60563c1a1b..d6aaae5cbb 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpIfOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpIfOperation.java @@ -25,7 +25,7 @@ import org.apache.tuweni.bytes.Bytes; public class RelativeJumpIfOperation extends RelativeJumpOperation { /** The constant OPCODE. */ - public static final int OPCODE = 0x5d; + public static final int OPCODE = 0xe1; /** * Instantiates a new Relative jump If operation. diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpOperation.java index b692865193..9f7b912f21 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpOperation.java @@ -26,7 +26,7 @@ import org.apache.tuweni.bytes.Bytes; public class RelativeJumpOperation extends AbstractFixedCostOperation { /** The constant OPCODE. */ - public static final int OPCODE = 0x5c; + public static final int OPCODE = 0xe0; /** * Instantiates a new Relative jump operation. diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpVectorOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpVectorOperation.java index bf5642aa15..1657d325c3 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpVectorOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/RelativeJumpVectorOperation.java @@ -27,7 +27,7 @@ import org.apache.tuweni.bytes.Bytes; public class RelativeJumpVectorOperation extends AbstractFixedCostOperation { /** The constant OPCODE. */ - public static final int OPCODE = 0x5e; + public static final int OPCODE = 0xe2; /** * Instantiates a new Relative jump vector operation. diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/RetFOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/RetFOperation.java index 29aaf5bddd..327dac1cb8 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/RetFOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/RetFOperation.java @@ -22,7 +22,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; public class RetFOperation extends AbstractOperation { /** The Opcode. */ - public static final int OPCODE = 0xb1; + public static final int OPCODE = 0xe4; /** The Ret F success. */ static final OperationResult retfSuccess = new OperationResult(4, null); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/TLoadOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/TLoadOperation.java index 3f05931db0..e813e72e1a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/TLoadOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/TLoadOperation.java @@ -33,7 +33,7 @@ public class TLoadOperation extends AbstractOperation { * @param gasCalculator gas calculator for costing */ public TLoadOperation(final GasCalculator gasCalculator) { - super(0xb3, "TLOAD", 1, 1, gasCalculator); + super(0x5C, "TLOAD", 1, 1, gasCalculator); } @Override diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/TStoreOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/TStoreOperation.java index 00d3de4dc1..d8b8730cd5 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/TStoreOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/TStoreOperation.java @@ -30,7 +30,7 @@ public class TStoreOperation extends AbstractOperation { * @param gasCalculator gas calculator for costing */ public TStoreOperation(final GasCalculator gasCalculator) { - super(0xb4, "TSTORE", 2, 0, gasCalculator); + super(0x5D, "TSTORE", 2, 0, gasCalculator); } @Override diff --git a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java index 33d105601a..7f8547d664 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/code/CodeV1Test.java @@ -44,7 +44,7 @@ class CodeV1Test { @Test void validCode() { String codeHex = - "0xEF0001 01000C 020003 000b 0002 0008 030000 00 00000000 02010001 01000002 60016002b00001b00002b1 01b1 60005360106000f3"; + "0xEF0001 01000C 020003 000b 0002 0008 030000 00 00000000 02010001 01000002 60016002e30001e30002e4 01e4 60005360106000f3"; final EOFLayout layout = EOFLayout.parseEOF(Bytes.fromHexString(codeHex.replace(" ", ""))); String validationError = validateCode(layout); @@ -54,7 +54,7 @@ class CodeV1Test { @ParameterizedTest @ValueSource( - strings = {"3000", "5000", "5c000000", "60005d000000", "60005e01000000", "fe00", "0000"}) + strings = {"3000", "5000", "e0000000", "6000e1000000", "6000e201000000", "fe00", "0000"}) void testValidOpcodes(final String code) { final String validationError = validateCode(Bytes.fromHexString(code), 1); assertThat(validationError).isNull(); @@ -90,15 +90,15 @@ class CodeV1Test { private static Stream testRjumpValidImmediateArguments() { return Stream.of( - "5c000000", - "5c00010000", - "5c00010000000000", - "5c0100" + NOOP_HEX.repeat(256) + ZERO_HEX, - "5c7fff" + NOOP_HEX.repeat(32767) + ZERO_HEX, - "5cfffd0000", - "005cfffc00", - NOOP_HEX.repeat(253) + "5cff0000", - NOOP_HEX.repeat(32765) + "5c800000") + "e0000000", + "e000010000", + "e000010000000000", + "e00100" + NOOP_HEX.repeat(256) + ZERO_HEX, + "e07fff" + NOOP_HEX.repeat(32767) + ZERO_HEX, + "e0fffd0000", + "00e0fffc00", + NOOP_HEX.repeat(253) + "e0ff0000", + NOOP_HEX.repeat(32765) + "e0800000") .map(Arguments::arguments); } @@ -111,16 +111,16 @@ class CodeV1Test { private static Stream testRjumpiValidImmediateArguments() { return Stream.of( - "60015d000000", - "60015d00010000", - "60015d00010000000000", - "60015d0100" + "5b".repeat(256) + ZERO_HEX, - "60015d7fff" + "5b".repeat(32767) + ZERO_HEX, - "60015dfffd0000", - "60015dfffb00", - NOOP_HEX.repeat(252) + "60015dff0000", - NOOP_HEX.repeat(32763) + "60015d800000", - "5d000000") + "6001e1000000", + "6001e100010000", + "6001e100010000000000", + "6001e10100" + "5b".repeat(256) + ZERO_HEX, + "6001e17fff" + "5b".repeat(32767) + ZERO_HEX, + "6001e1fffd0000", + "6001e1fffb00", + NOOP_HEX.repeat(252) + "6001e1ff0000", + NOOP_HEX.repeat(32763) + "6001e1800000", + "e1000000") .map(Arguments::arguments); } @@ -133,14 +133,14 @@ class CodeV1Test { private static Stream rjumptableValidImmediateArguments() { return Stream.of( - "60015e01000000", - "60015e02000000010000", - "60015e03000000040100" + "5b".repeat(256) + ZERO_HEX, - "60015e040000000401007fff" + "5b".repeat(32767) + ZERO_HEX, - "60015e01fffc0000", - "5b".repeat(248) + "60015e02fffaff0000", - "5b".repeat(32760) + "60015e02fffa800000", - "5e01000000") + "6001e201000000", + "6001e202000000010000", + "6001e203000000040100" + "5b".repeat(256) + ZERO_HEX, + "6001e2040000000401007fff" + "5b".repeat(32767) + ZERO_HEX, + "6001e201fffc0000", + "5b".repeat(248) + "6001e202fffaff0000", + "5b".repeat(32760) + "6001e202fffa800000", + "e201000000") .map(Arguments::arguments); } @@ -157,12 +157,11 @@ class CodeV1Test { IntStream.of(0x1e, 0x1f), IntStream.rangeClosed(0x21, 0x2f), IntStream.rangeClosed(0x49, 0x4f), - // IntStream.of(0x5f), // PUSH0 IntStream.rangeClosed(0xa5, 0xaf), - IntStream.rangeClosed(0xb3, 0xbf), + IntStream.rangeClosed(0xb0, 0xbf), IntStream.rangeClosed(0xc0, 0xcf), IntStream.rangeClosed(0xd0, 0xdf), - IntStream.rangeClosed(0xe0, 0xef), + IntStream.rangeClosed(0xe5, 0xef), IntStream.of(0xf6, 0xf7, 0xf8, 0xf9, 0xfb, 0xfc)) .flatMapToInt(i -> i) .mapToObj(i -> String.format("%02x", i) + ZERO_HEX) @@ -185,14 +184,14 @@ class CodeV1Test { } @ParameterizedTest - @ValueSource(strings = {"5c", "5c00"}) + @ValueSource(strings = {"e0", "e000"}) void testRjumpTruncatedImmediate(final String code) { final String validationError = validateCode(Bytes.fromHexString(code), 1); assertThat(validationError).isEqualTo("Truncated relative jump offset"); } @ParameterizedTest - @ValueSource(strings = {"60015d", "60015d00"}) + @ValueSource(strings = {"6001e1", "6001e100"}) void testRjumpiTruncatedImmediate(final String code) { final String validationError = validateCode(Bytes.fromHexString(code), 1); assertThat(validationError).isEqualTo("Truncated relative jump offset"); @@ -201,12 +200,12 @@ class CodeV1Test { @ParameterizedTest @ValueSource( strings = { - "60015e", - "60015e01", - "60015e0100", - "60015e030000", - "60015e0300000001", - "60015e030000000100" + "6001e2", + "6001e201", + "6001e20100", + "6001e2030000", + "6001e20300000001", + "6001e2030000000100" }) void testRjumpvTruncatedImmediate(final String code) { final String validationError = validateCode(Bytes.fromHexString(code), 1); @@ -216,14 +215,14 @@ class CodeV1Test { @ParameterizedTest @ValueSource( strings = { - "5c0000", - "5c000100", - "5cfffc00", - "60015d0000", - "60015d000100", - "60015dfffa00", - "60015e01000100", - "60015e01fff900" + "e00000", + "e0000100", + "e0fffc00", + "6001e10000", + "6001e1000100", + "6001e1fffa00", + "6001e201000100", + "6001e201fff900" }) void testRjumpsOutOfBounds(final String code) { final String validationError = validateCode(Bytes.fromHexString(code), 1); @@ -235,47 +234,47 @@ class CodeV1Test { @ValueSource( strings = { // RJUMP into RJUMP immediate - "5cffff00", - "5cfffe00", - "5c00015c000000", - "5c00025c000000", + "e0ffff00", + "e0fffe00", + "e00001e0000000", + "e00002e0000000", // RJUMPI into RJUMP immediate - "60015d00015c000000", - "60015d00025c000000", + "6001e10001e0000000", + "6001e10002e0000000", // RJUMPV into RJUMP immediate - "60015e0100015c000000", - "60015e0100025c000000", + "6001e2010001e0000000", + "6001e2010002e0000000", // RJUMP into RJUMPI immediate - "5c000360015d000000", - "5c000460015d000000", + "e000036001e1000000", + "e000046001e1000000", // RJUMPI into RJUMPI immediate - "60015dffff00", - "60015dfffe00", - "60015d000360015d000000", - "60015d000460015d000000", + "6001e1ffff00", + "6001e1fffe00", + "6001e100036001e1000000", + "6001e100046001e1000000", // RJUMPV into RJUMPI immediate - "60015e01000360015d000000", - "60015e01000460015d000000", + "6001e20100036001e1000000", + "6001e20100046001e1000000", // RJUMP into RJUMPV immediate - "5c00015e01000000", - "5c00025e01000000", - "5c00035e01000000", + "e00001e201000000", + "e00002e201000000", + "e00003e201000000", // RJUMPI into RJUMPV immediate - "60015d00015e01000000", - "60015d00025e01000000", - "60015d00035e01000000", + "6001e10001e201000000", + "6001e10002e201000000", + "6001e10003e201000000", // RJUMPV into RJUMPV immediate - "60015e01ffff00", - "60015e01fffe00", - "60015e01fffd00", - "60015e0100015e01000000", - "60015e0100025e01000000", - "60015e0100035e01000000", - "60015e0100015e020000fff400", - "60015e0100025e020000fff400", - "60015e0100035e020000fff400", - "60015e0100045e020000fff400", - "60015e0100055e020000fff400" + "6001e201ffff00", + "6001e201fffe00", + "6001e201fffd00", + "6001e2010001e201000000", + "6001e2010002e201000000", + "6001e2010003e201000000", + "6001e2010001e2020000fff400", + "6001e2010002e2020000fff400", + "6001e2010003e2020000fff400", + "6001e2010004e2020000fff400", + "6001e2010005e2020000fff400" }) void testRjumpsIntoImmediate(final String code) { final String validationError = validateCode(Bytes.fromHexString(code), 1); @@ -291,21 +290,21 @@ class CodeV1Test { .mapToObj( offset -> Stream.of( - String.format("5c00%02x", offset) + String.format("e000%02x", offset) + // RJUMP offset String.format("%02x", 0x60 + n - 1) + // PUSHn ZERO_HEX.repeat(n) + // push data ZERO_HEX, // STOP - String.format("60015d00%02x", offset) + String.format("6001e100%02x", offset) + // PUSH1 1 RJUMI offset String.format("%02x", 0x60 + n - 1) + // PUSHn ZERO_HEX.repeat(n) + // push data ZERO_HEX, // STOP - String.format("60015e0100%02x", offset) + String.format("6001e20100%02x", offset) + String.format("%02x", 0x60 + n - 1) + // PUSHn ZERO_HEX.repeat(n) @@ -318,21 +317,21 @@ class CodeV1Test { } @ParameterizedTest - @ValueSource(strings = {"60015e0000"}) + @ValueSource(strings = {"6001e20000"}) void testRjumpvEmptyTable(final String code) { final String validationError = validateCode(Bytes.fromHexString(code), 1); assertThat(validationError).isEqualTo("Empty jump table"); } @ParameterizedTest - @ValueSource(strings = {"b0", "b000"}) + @ValueSource(strings = {"e3", "e300"}) void testCallFTruncated(final String code) { final String validationError = validateCode(Bytes.fromHexString(code), 1); assertThat(validationError).isEqualTo("Truncated CALLF"); } @ParameterizedTest - @ValueSource(strings = {"b2", "b200"}) + @ValueSource(strings = {"e5", "e500"}) @Disabled("Out of Shahghai, will likely return in Cancun or Prague") void testJumpCallFTruncated(final String code) { final String validationError = validateCode(Bytes.fromHexString(code), 1); @@ -340,14 +339,14 @@ class CodeV1Test { } @ParameterizedTest - @ValueSource(strings = {"b00004", "b003ff", "b0ffff"}) + @ValueSource(strings = {"e30004", "e303ff", "e3ffff"}) void testCallFWrongSection(final String code) { final String validationError = validateCode(Bytes.fromHexString(code), 3); assertThat(validationError).startsWith("CALLF to non-existent section -"); } @ParameterizedTest - @ValueSource(strings = {"b20004", "b203ff", "b2ffff"}) + @ValueSource(strings = {"e50004", "e503ff", "e5ffff"}) @Disabled("Out of Shahghai, will likely return in Cancun or Prague") void testJumpFWrongSection(final String code) { final String validationError = validateCode(Bytes.fromHexString(code), 3); @@ -355,14 +354,14 @@ class CodeV1Test { } @ParameterizedTest - @ValueSource(strings = {"b0000100", "b0000200", "b0000000"}) + @ValueSource(strings = {"e3000100", "e3000200", "e3000000"}) void testCallFValid(final String code) { final String validationError = validateCode(Bytes.fromHexString(code), 3); assertThat(validationError).isNull(); } @ParameterizedTest - @ValueSource(strings = {"b20001", "b20002", "b20000"}) + @ValueSource(strings = {"e50001", "e50002", "e50000"}) @Disabled("Out of Shahghai, will likely return in Cancun or Prague") void testJumpFValid(final String code) { final String validationError = validateCode(Bytes.fromHexString(code), 3); @@ -378,26 +377,26 @@ class CodeV1Test { private static Stream immediateContainsOpcodeArguments() { return Stream.of( - // 0x5c byte which could be interpreted a RJUMP, but it's not because it's in PUSH data - "605c001000", - "61005c001000", - // 0x5d byte which could be interpreted a RJUMPI, but it's not because it's in PUSH data - "605d001000", - "61005d001000", - // 0x5e byte which could be interpreted a RJUMPV, but it's not because it's in PUSH data - "605e01000000", - "61005e01000000", + // 0xe0 byte which could be interpreted a RJUMP, but it's not because it's in PUSH data + "60e0001000", + "6100e0001000", + // 0xe1 byte which could be interpreted a RJUMPI, but it's not because it's in PUSH data + "60e1001000", + "6100e1001000", + // 0xe2 byte which could be interpreted a RJUMPV, but it's not because it's in PUSH data + "60e201000000", + "6100e201000000", // 0x60 byte which could be interpreted as PUSH, but it's not because it's in RJUMP data // offset = -160 - "5b".repeat(160) + "5cff6000", + "5b".repeat(160) + "e0ff6000", // 0x60 byte which could be interpreted as PUSH, but it's not because it's in RJUMPI // data // offset = -160 - "5b".repeat(160) + "5dff6000", + "5b".repeat(160) + "e1ff6000", // 0x60 byte which could be interpreted as PUSH, but it's not because it's in RJUMPV // data // offset = -160 - "5b".repeat(160) + "5e01ff6000") + "5b".repeat(160) + "e201ff6000") .map(Arguments::arguments); } @@ -497,48 +496,48 @@ class CodeV1Test { static Stream stackRJumpForward() { return Stream.of( - Arguments.of("RJUMP 0", null, 0, List.of(List.of("5C0000 00", 0, 0, 0))), + Arguments.of("RJUMP 0", null, 0, List.of(List.of("e00000 00", 0, 0, 0))), Arguments.of( "RJUMP 1 w/ dead code", "Dead code detected in section 0", 0, - List.of(List.of("5C0001 43 00", 0, 0, 0))), + List.of(List.of("e00001 43 00", 0, 0, 0))), Arguments.of( "RJUMP 2 w/ dead code", "Dead code detected in section 0", 0, - List.of(List.of("5C0002 43 50 00", 0, 0, 0))), + List.of(List.of("e00002 43 50 00", 0, 0, 0))), Arguments.of( "RJUMP 3 and -10", null, 0, - List.of(List.of("5C0003 01 50 00 6001 6001 5Cfff6", 0, 0, 2)))); + List.of(List.of("e00003 01 50 00 6001 6001 e0fff6", 0, 0, 2)))); } static Stream stackRJumpBackward() { return Stream.of( - Arguments.of("RJUMP -3", null, 0, List.of(List.of("5Cfffd", 0, 0, 0))), - Arguments.of("RJUMP -4", null, 0, List.of(List.of("5B 5Cfffc", 0, 0, 0))), + Arguments.of("RJUMP -3", null, 0, List.of(List.of("e0fffd", 0, 0, 0))), + Arguments.of("RJUMP -4", null, 0, List.of(List.of("5B e0fffc", 0, 0, 0))), Arguments.of( "RJUMP -4 unmatched stack", "Jump into code stack height (0) does not match previous value (1)", 0, - List.of(List.of("43 5Cfffc", 0, 0, 0))), + List.of(List.of("43 e0fffc", 0, 0, 0))), Arguments.of( "RJUMP -4 unmatched stack", "Jump into code stack height (1) does not match previous value (0)", 0, - List.of(List.of("43 50 5Cfffc 00", 0, 0, 0))), - Arguments.of("RJUMP -3 matched stack", null, 0, List.of(List.of("43 50 5Cfffd", 0, 0, 1))), + List.of(List.of("43 50 e0fffc 00", 0, 0, 0))), + Arguments.of("RJUMP -3 matched stack", null, 0, List.of(List.of("43 50 e0fffd", 0, 0, 1))), Arguments.of( - "RJUMP -4 matched stack", null, 0, List.of(List.of("43 50 5B 5Cfffc", 0, 0, 1))), + "RJUMP -4 matched stack", null, 0, List.of(List.of("43 50 5B e0fffc", 0, 0, 1))), Arguments.of( - "RJUMP -5 matched stack", null, 0, List.of(List.of("43 50 43 5Cfffb", 0, 0, 1))), + "RJUMP -5 matched stack", null, 0, List.of(List.of("43 50 43 e0fffb", 0, 0, 1))), Arguments.of( "RJUMP -4 unmatched stack", "Jump into code stack height (0) does not match previous value (1)", 0, - List.of(List.of("43 50 43 5Cfffc 50 00", 0, 0, 0)))); + List.of(List.of("43 50 43 e0fffc 50 00", 0, 0, 0)))); } static Stream stackRJumpI() { @@ -547,61 +546,61 @@ class CodeV1Test { "RJUMPI Each branch ending with STOP", null, 0, - List.of(List.of("60ff 6001 5D0002 50 00 50 00", 0, 0, 2))), + List.of(List.of("60ff 6001 e10002 50 00 50 00", 0, 0, 2))), Arguments.of( "RJUMPI One branch ending with RJUMP", null, 0, - List.of(List.of("60ff 6001 5D0004 50 5C0001 50 00", 0, 0, 2))), + List.of(List.of("60ff 6001 e10004 50 e00001 50 00", 0, 0, 2))), Arguments.of( "RJUMPI Fallthrough", null, 0, - List.of(List.of("60ff 6001 5D0004 80 80 50 50 50 00", 0, 0, 3))), + List.of(List.of("60ff 6001 e10004 80 80 50 50 50 00", 0, 0, 3))), Arguments.of( - "RJUMPI Offset 0", null, 0, List.of(List.of("60ff 6001 5D0000 50 00", 0, 0, 2))), + "RJUMPI Offset 0", null, 0, List.of(List.of("60ff 6001 e10000 50 00", 0, 0, 2))), Arguments.of( "Simple loop (RJUMPI offset = -5)", null, 0, - List.of(List.of("6001 60ff 81 02 80 5Dfffa 50 50 00", 0, 0, 3))), + List.of(List.of("6001 60ff 81 02 80 e1fffa 50 50 00", 0, 0, 3))), Arguments.of( "RJUMPI One branch increasing max stack more stack than another", null, 0, - List.of(List.of("6001 5D0007 30 30 30 50 50 50 00 30 50 00", 0, 0, 3))), + List.of(List.of("6001 e10007 30 30 30 50 50 50 00 30 50 00", 0, 0, 3))), Arguments.of( "RJUMPI One branch increasing max stack more stack than another II", null, 0, - List.of(List.of("6001 5D0003 30 50 00 30 30 30 50 50 50 00", 0, 0, 3))), + List.of(List.of("6001 e10003 30 50 00 30 30 30 50 50 50 00", 0, 0, 3))), Arguments.of( "RJUMPI Missing stack argument", - "Operation 0x5D requires stack of 1 but only has 0 items", + "Operation 0xE1 requires stack of 1 but only has 0 items", 0, - List.of(List.of("5D0000 00", 0, 0, 0))), + List.of(List.of("e10000 00", 0, 0, 0))), Arguments.of( "Stack underflow one branch", "Operation 0x02 requires stack of 2 but only has 1 items", 0, - List.of(List.of("60ff 6001 5D0002 50 00 02 50 00", 0, 0, 0))), + List.of(List.of("60ff 6001 e10002 50 00 02 50 00", 0, 0, 0))), Arguments.of( "Stack underflow another branch", "Operation 0x02 requires stack of 2 but only has 1 items", 0, - List.of(List.of("60ff 6001 5D0002 02 00 19 50 00", 0, 0, 0))), + List.of(List.of("60ff 6001 e10002 02 00 19 50 00", 0, 0, 0))), // this depends on requiring stacks to be "clean" returns Arguments.of( "RJUMPI Stack not empty in the end of one branch", null, 0, - List.of(List.of("60ff 6001 5D0002 50 00 19 00", 0, 0, 2))), + List.of(List.of("60ff 6001 e10002 50 00 19 00", 0, 0, 2))), // this depends on requiring stacks to be "clean" returns Arguments.of( "RJUMPI Stack not empty in the end of one branch II", null, 0, - List.of(List.of("60ff 6001 5D0002 19 00 50 00", 0, 0, 2)))); + List.of(List.of("60ff 6001 e10002 19 00 50 00", 0, 0, 2)))); } static Stream stackCallF() { @@ -610,99 +609,99 @@ class CodeV1Test { "0 input 0 output", null, 0, - List.of(List.of("B00001 00", 0, 0, 0), List.of("b1", 0, 0, 0))), + List.of(List.of("e30001 00", 0, 0, 0), List.of("e4", 0, 0, 0))), Arguments.of( "0 inputs, 0 output 3 sections", null, 0, - List.of(List.of("B00002 00", 0, 0, 0), List.of("b1", 1, 1, 1), List.of("b1", 0, 0, 0))), + List.of(List.of("e30002 00", 0, 0, 0), List.of("e4", 1, 1, 1), List.of("e4", 0, 0, 0))), Arguments.of( "more than 0 inputs", null, 0, - List.of(List.of("30 B00001 00", 0, 0, 1), List.of("00", 1, 0, 1))), + List.of(List.of("30 e30001 00", 0, 0, 1), List.of("00", 1, 0, 1))), Arguments.of( "forwarding an argument", null, 1, - List.of(List.of("00", 0, 0, 0), List.of("B00002 00", 1, 0, 1), List.of("00", 1, 0, 1))), + List.of(List.of("00", 0, 0, 0), List.of("e30002 00", 1, 0, 1), List.of("00", 1, 0, 1))), Arguments.of( "more than 1 inputs", null, 0, - List.of(List.of("30 80 B00001 00", 0, 0, 2), List.of("00", 2, 0, 2))), + List.of(List.of("30 80 e30001 00", 0, 0, 2), List.of("00", 2, 0, 2))), Arguments.of( "more than 0 outputs", null, 0, - List.of(List.of("B00001 50 00", 0, 0, 1), List.of("3000", 0, 1, 1))), + List.of(List.of("e30001 50 00", 0, 0, 1), List.of("3000", 0, 1, 1))), Arguments.of( "more than 0 outputs 3 sections", null, 0, List.of( - List.of("B00002 50 00", 0, 0, 1), + List.of("e30002 50 00", 0, 0, 1), List.of("00", 0, 0, 0), List.of("30305000", 0, 1, 2))), Arguments.of( "more than 1 outputs", null, 0, - List.of(List.of("B00001 50 50 00", 0, 0, 2), List.of("303000", 0, 2, 2))), + List.of(List.of("e30001 50 50 00", 0, 0, 2), List.of("303000", 0, 2, 2))), Arguments.of( "more than 0 inputs, more than 0 outputs", null, 0, List.of( - List.of("30 30 B00001 50 50 50 00", 0, 0, 3), - List.of("30 30 B00001 50 50 00", 2, 3, 5))), - Arguments.of("recursion", null, 0, List.of(List.of("B00000 00", 0, 0, 0))), + List.of("30 30 e30001 50 50 50 00", 0, 0, 3), + List.of("30 30 e30001 50 50 00", 2, 3, 5))), + Arguments.of("recursion", null, 0, List.of(List.of("e30000 00", 0, 0, 0))), Arguments.of( "recursion 2 inputs", null, 1, - List.of(List.of("00", 0, 0, 0), List.of("B00000 00", 2, 0, 2))), + List.of(List.of("00", 0, 0, 0), List.of("e30000 00", 2, 0, 2))), Arguments.of( "recursion 2 inputs 2 outputs", null, 1, - List.of(List.of("00", 0, 0, 0), List.of("B00000 50 50 00", 2, 2, 2))), + List.of(List.of("00", 0, 0, 0), List.of("e30000 50 50 00", 2, 2, 2))), Arguments.of( "recursion 2 inputs 1 output", null, 1, - List.of(List.of("00", 0, 0, 0), List.of("30 30 B00001 50 50 50 00", 2, 1, 4))), + List.of(List.of("00", 0, 0, 0), List.of("30 30 e30001 50 50 50 00", 2, 1, 4))), Arguments.of( "multiple CALLFs with different types", null, 1, List.of( List.of("00", 0, 0, 0), - List.of("44 B00002 80 80 B00003 44 80 B00004 50 50 00", 0, 0, 3), + List.of("44 e30002 80 80 e30003 44 80 e30004 50 50 00", 0, 0, 3), List.of("3030505000", 1, 1, 3), List.of("50505000", 3, 0, 3), List.of("00", 2, 2, 2))), Arguments.of( "underflow", - "Operation 0xB0 requires stack of 1 but only has 0 items", + "Operation 0xE3 requires stack of 1 but only has 0 items", 0, - List.of(List.of("B00001 00", 0, 0, 0), List.of("00", 1, 0, 0))), + List.of(List.of("e30001 00", 0, 0, 0), List.of("00", 1, 0, 0))), Arguments.of( "underflow 2", - "Operation 0xB0 requires stack of 2 but only has 1 items", + "Operation 0xE3 requires stack of 2 but only has 1 items", 0, - List.of(List.of("30 B00001 00", 0, 0, 0), List.of("00", 2, 0, 2))), + List.of(List.of("30 e30001 00", 0, 0, 0), List.of("00", 2, 0, 2))), Arguments.of( "underflow 3", - "Operation 0xB0 requires stack of 1 but only has 0 items", + "Operation 0xE3 requires stack of 1 but only has 0 items", 1, - List.of(List.of("00", 0, 0, 0), List.of("50 B00001 00", 1, 0, 1))), + List.of(List.of("00", 0, 0, 0), List.of("50 e30001 00", 1, 0, 1))), Arguments.of( "underflow 4", - "Operation 0xB0 requires stack of 3 but only has 2 items", + "Operation 0xE3 requires stack of 3 but only has 2 items", 0, List.of( - List.of("44 B00001 80 B00002 00", 0, 0, 0), + List.of("44 e30001 80 e30002 00", 0, 0, 0), List.of("00", 1, 1, 1), List.of("00", 3, 0, 3)))); } @@ -713,63 +712,63 @@ class CodeV1Test { "0 outputs at section 0", null, 0, - List.of(List.of("B1", 0, 0, 0), List.of("00", 0, 0, 0))), + List.of(List.of("e4", 0, 0, 0), List.of("00", 0, 0, 0))), Arguments.of( "0 outputs at section 1", null, 1, - List.of(List.of("00", 0, 0, 0), List.of("B1", 0, 0, 0))), + List.of(List.of("00", 0, 0, 0), List.of("e4", 0, 0, 0))), Arguments.of( "0 outputs at section 2", null, 2, - List.of(List.of("00", 0, 0, 0), List.of("00", 1, 1, 1), List.of("B1", 0, 0, 0))), + List.of(List.of("00", 0, 0, 0), List.of("00", 1, 1, 1), List.of("e4", 0, 0, 0))), Arguments.of( "more than 0 outputs section 0", null, 0, - List.of(List.of("44 50 B1", 0, 0, 1), List.of("4400", 0, 1, 1))), + List.of(List.of("44 50 e4", 0, 0, 1), List.of("4400", 0, 1, 1))), Arguments.of( "more than 0 outputs section 0", null, 1, - List.of(List.of("00", 0, 0, 0), List.of("44 B1", 0, 1, 1))), + List.of(List.of("00", 0, 0, 0), List.of("44 e4", 0, 1, 1))), Arguments.of( "more than 1 outputs section 1", null, 1, - List.of(List.of("00", 0, 0, 0), List.of("44 80 B1", 0, 2, 2))), + List.of(List.of("00", 0, 0, 0), List.of("44 80 e4", 0, 2, 2))), Arguments.of( "Forwarding return values", null, 1, - List.of(List.of("00", 0, 0, 0), List.of("B1", 1, 1, 1))), + List.of(List.of("00", 0, 0, 0), List.of("e4", 1, 1, 1))), Arguments.of( "Forwarding of return values 2", null, 1, List.of( - List.of("00", 0, 0, 0), List.of("B00002 B1", 0, 1, 1), List.of("3000", 0, 1, 1))), + List.of("00", 0, 0, 0), List.of("e30002 e4", 0, 1, 1), List.of("3000", 0, 1, 1))), Arguments.of( "Multiple RETFs", null, 1, - List.of(List.of("00", 0, 0, 0), List.of("5D0003 44 80 B1 30 80 B1", 1, 2, 2))), + List.of(List.of("00", 0, 0, 0), List.of("e10003 44 80 e4 30 80 e4", 1, 2, 2))), Arguments.of( "underflow 1", "Section return (RETF) calculated height 0x0 does not match configured height 0x1", 1, - List.of(List.of("00", 0, 0, 0), List.of("B1", 0, 1, 0))), + List.of(List.of("00", 0, 0, 0), List.of("e4", 0, 1, 0))), Arguments.of( "underflow 2", "Section return (RETF) calculated height 0x1 does not match configured height 0x2", 1, - List.of(List.of("00", 0, 0, 0), List.of("44 B1", 0, 2, 1))), + List.of(List.of("00", 0, 0, 0), List.of("44 e4", 0, 2, 1))), Arguments.of( "underflow 3", "Section return (RETF) calculated height 0x1 does not match configured height 0x2", 1, - List.of(List.of("00", 0, 0, 0), List.of("5D0003 44 80 B1 30 B1", 1, 2, 2)))); + List.of(List.of("00", 0, 0, 0), List.of("e10003 44 80 e4 30 e4", 1, 2, 2)))); } static Stream stackUnreachable() { @@ -783,12 +782,12 @@ class CodeV1Test { "Max stack not changed by unreachable code RETf", "Dead code detected in section 0", 0, - List.of(List.of("30 50 B1 30 30 30 50 50 50 00", 0, 0, 1))), + List.of(List.of("30 50 e4 30 30 30 50 50 50 00", 0, 0, 1))), Arguments.of( "Max stack not changed by unreachable code RJUMP", "Dead code detected in section 0", 0, - List.of(List.of("30 50 5C0006 30 30 30 50 50 50 00", 0, 0, 1))), + List.of(List.of("30 50 e00006 30 30 30 50 50 50 00", 0, 0, 1))), Arguments.of( "Stack underflow in unreachable code", "Dead code detected in section 0", @@ -798,12 +797,12 @@ class CodeV1Test { "Stack underflow in unreachable code RETF", "Dead code detected in section 0", 0, - List.of(List.of("30 50 B1 50 00", 0, 0, 1))), + List.of(List.of("30 50 e4 50 00", 0, 0, 1))), Arguments.of( "Stack underflow in unreachable code RJUMP", "Dead code detected in section 0", 0, - List.of(List.of("30 50 5C0001 50 00", 0, 0, 1)))); + List.of(List.of("30 50 e00001 50 00", 0, 0, 1)))); } static Stream stackHeight() { @@ -812,12 +811,12 @@ class CodeV1Test { "Stack height mismatch backwards", "Jump into code stack height (0) does not match previous value (1)", 0, - List.of(List.of("30 5Cfffc00", 0, 0, 1))), + List.of(List.of("30 e0fffc00", 0, 0, 1))), Arguments.of( "Stack height mismatch forwards", "Jump into code stack height (3) does not match previous value (0)", 0, - List.of(List.of("305D0003303030303000", 0, 0, 2)))); + List.of(List.of("30e10003303030303000", 0, 0, 2)))); } static Stream invalidInstructions() { diff --git a/evm/src/test/java/org/hyperledger/besu/evm/processor/ContractCreationProcessorTest.java b/evm/src/test/java/org/hyperledger/besu/evm/processor/ContractCreationProcessorTest.java index 8a28bdf41e..d84d44ea7a 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/processor/ContractCreationProcessorTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/processor/ContractCreationProcessorTest.java @@ -159,7 +159,7 @@ class ContractCreationProcessorTest { Collections.emptyList()); final Bytes contractCode = Bytes.fromHexString( - "0xEF000101000C020003000b000200080300000000000002020100020100000260016002b00001b00002b101b160005360106000f3"); + "0xEF000101000C020003000b000200080300000000000002020100020100000260016002e30001e30002e401e460005360106000f3"); final MessageFrame messageFrame = new TestMessageFrameBuilder().build(); messageFrame.setOutputData(contractCode); messageFrame.setGasRemaining(100L); @@ -182,7 +182,7 @@ class ContractCreationProcessorTest { final Bytes contractCode = Bytes.fromHexString("6030602001"); final Bytes initCode = Bytes.fromHexString( - "0xEF000101000C020003000b000200080300000000000002020100020100000260016002b00001b00002b101b160005360106000f3"); + "0xEF000101000C020003000b000200080300000000000002020100020100000260016002e30001e30002e401e460005360106000f3"); final MessageFrame messageFrame = new TestMessageFrameBuilder().code(CodeFactory.createCode(initCode, 1, true)).build(); messageFrame.setOutputData(contractCode); diff --git a/evm/src/test/java/org/hyperledger/besu/evm/testutils/ByteCodeBuilder.java b/evm/src/test/java/org/hyperledger/besu/evm/testutils/ByteCodeBuilder.java index e95ba08dd3..19276d1afa 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/testutils/ByteCodeBuilder.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/testutils/ByteCodeBuilder.java @@ -38,8 +38,8 @@ public class ByteCodeBuilder { RETURNDATACOPY("3e"), REVERT("fd"), STATICCALL("fa"), - TLOAD("b3"), - TSTORE("b4"); + TLOAD("5c"), + TSTORE("5d"); private final String value; @@ -53,20 +53,13 @@ public class ByteCodeBuilder { } } - StringBuilder byteCode = new StringBuilder("0x"); + final StringBuilder byteCode = new StringBuilder("0x"); @Override public String toString() { return byteCode.toString(); } - /** - * @return Bytecode as Bytes - */ - public Bytes toBytes() { - return Bytes.fromHexString(byteCode.toString()); - } - /** * Operation to push the value to the EVM stack * @@ -106,8 +99,10 @@ public class ByteCodeBuilder { private String standardizeByteString(final UInt256 value) { String byteString = value.toMinimalBytes().toUnprefixedHexString(); - while (byteString.length() < 2) { + if (byteString.length() % 2 == 1) { byteString = "0" + byteString; + } else if (byteString.length() == 0) { + byteString = "00"; } return byteString; } @@ -120,8 +115,7 @@ public class ByteCodeBuilder { * @return this */ public ByteCodeBuilder tstore(final int key, final int value) { - this.push(value); - this.push(key); + this.push(value).push(key); byteCode.append(Operation.TSTORE); return this; } @@ -145,8 +139,7 @@ public class ByteCodeBuilder { * @return this */ public ByteCodeBuilder dataOnStackToMemory(final int key) { - this.push(key); - this.op(Operation.MSTORE); + this.push(key).op(Operation.MSTORE); return this; } @@ -158,9 +151,7 @@ public class ByteCodeBuilder { * @return this */ public ByteCodeBuilder returnValueAtMemory(final int size, final int key) { - this.push(size); - this.push(key); - this.op(Operation.RETURN); + this.push(size).push(key).op(Operation.RETURN); return this; } @@ -175,14 +166,14 @@ public class ByteCodeBuilder { public ByteCodeBuilder call( final Operation callType, final Address address, final UInt256 gasLimit) { callTypeCheck(callType); - this.push(0); - this.push(0); - this.push(0); - this.push(0); - this.push(0); - this.push(Bytes.fromHexString(address.toHexString())); - this.push(gasLimit.toMinimalBytes()); - this.op(callType); + this.push(0) + .push(0) + .push(0) + .push(0) + .push(0) + .push(Bytes.fromHexString(address.toHexString())) + .push(gasLimit.toMinimalBytes()) + .op(callType); return this; } @@ -233,14 +224,14 @@ public class ByteCodeBuilder { dataOnStackToMemory(0); } - this.push(0); - this.push(0); - this.push(32); - this.push(0); - this.push(0); - this.push(Bytes.fromHexString(address.toHexString())); - this.push(gasLimit.toMinimalBytes()); - this.op(callType); + this.push(0) + .push(0) + .push(32) + .push(0) + .push(0) + .push(Bytes.fromHexString(address.toHexString())) + .push(gasLimit.toMinimalBytes()) + .op(callType); return this; } @@ -250,9 +241,7 @@ public class ByteCodeBuilder { * @return this */ public ByteCodeBuilder returnInnerCallResults() { - this.push(32); - this.push(0); - this.push(0); + this.push(32).push(0).push(0); byteCode.append(Operation.RETURNDATACOPY); this.returnValueAtMemory(32, 0); return this;