VM impl:
+ SDIV, SMOD, MOD, SLT, SGT ops implemented and unittested + Gas calculation for memory & storage
This commit is contained in:
parent
517bb2cec1
commit
b9d551d2fa
|
@ -41,6 +41,11 @@ public class DataWord {
|
|||
return new BigInteger(1, data);
|
||||
}
|
||||
|
||||
public BigInteger sValue(){
|
||||
return new BigInteger(data);
|
||||
}
|
||||
|
||||
|
||||
public boolean isZero(){
|
||||
|
||||
byte result = 0;
|
||||
|
@ -50,6 +55,17 @@ public class DataWord {
|
|||
return result == 0;
|
||||
}
|
||||
|
||||
// only in case of signed operation
|
||||
// when the number is explicit defined
|
||||
// as negative
|
||||
public boolean isNegative(){
|
||||
|
||||
int result = data[0] & 0x80;
|
||||
|
||||
return result == 0x80;
|
||||
}
|
||||
|
||||
|
||||
public DataWord and(DataWord w2){
|
||||
|
||||
for (int i = 0; i < this.data.length; ++i){
|
||||
|
@ -144,6 +160,26 @@ public class DataWord {
|
|||
this.data = data.array();
|
||||
}
|
||||
|
||||
// todo: improve with no BigInteger
|
||||
public void sDiv(DataWord word){
|
||||
|
||||
if (word.isZero()){
|
||||
this.and(ZERO);
|
||||
return;
|
||||
}
|
||||
|
||||
BigInteger result = sValue().divide( word.sValue() );
|
||||
byte[] bytes = result.toByteArray();
|
||||
|
||||
ByteBuffer data = ByteBuffer.allocate(32);
|
||||
if (result.compareTo(BigInteger.ZERO) == -1)
|
||||
Arrays.fill(data.array(), (byte) 0xFF);
|
||||
|
||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
||||
this.data = data.array();
|
||||
}
|
||||
|
||||
|
||||
// todo: improve with no BigInteger
|
||||
public void sub(DataWord word){
|
||||
|
||||
|
@ -166,6 +202,40 @@ public class DataWord {
|
|||
this.data = data.array();
|
||||
}
|
||||
|
||||
// todo: improve with no BigInteger
|
||||
public void mod(DataWord word){
|
||||
|
||||
if (word.isZero()){
|
||||
this.and(ZERO);
|
||||
return;
|
||||
}
|
||||
|
||||
BigInteger result = value().mod(word.value());
|
||||
byte[] bytes = result.toByteArray();
|
||||
|
||||
ByteBuffer data = ByteBuffer.allocate(32);
|
||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
||||
this.data = data.array();
|
||||
}
|
||||
|
||||
// todo: improve with no BigInteger
|
||||
public void sMod(DataWord word){
|
||||
|
||||
if (word.isZero() || word.isNegative()){
|
||||
this.and(ZERO);
|
||||
return;
|
||||
}
|
||||
|
||||
BigInteger result = sValue().mod( word.sValue());
|
||||
byte[] bytes = result.toByteArray();
|
||||
|
||||
ByteBuffer data = ByteBuffer.allocate(32);
|
||||
if (result.compareTo(BigInteger.ZERO) == -1)
|
||||
Arrays.fill(data.array(), (byte) 0xFF);
|
||||
|
||||
System.arraycopy(bytes, 0, data.array(), 32 - bytes.length, bytes.length);
|
||||
this.data = data.array();
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return Hex.toHexString(data);
|
||||
|
|
|
@ -190,7 +190,7 @@ public class Program {
|
|||
|
||||
public void spendGas(int gasValue){
|
||||
// todo: check it against avail gas
|
||||
// todo: out of gas will revert the changes
|
||||
// todo: out of gas will revert the changes [YP 5, 6 ]
|
||||
spendGas += gasValue;
|
||||
}
|
||||
|
||||
|
@ -257,6 +257,9 @@ public class Program {
|
|||
|
||||
|
||||
public void fullTrace(){
|
||||
|
||||
// todo: add gas to full trace calc
|
||||
|
||||
if (logger.isDebugEnabled()){
|
||||
|
||||
StringBuilder stackData = new StringBuilder();
|
||||
|
|
|
@ -30,6 +30,7 @@ public class VM {
|
|||
byte op = program.getCurrentOp();
|
||||
logger.debug("Op: {}" ,OpCode.code(op).name());
|
||||
|
||||
int oldMemSize = program.getMemSize();
|
||||
|
||||
switch (OpCode.code(op)) {
|
||||
case SHA3:
|
||||
|
@ -110,12 +111,33 @@ public class VM {
|
|||
program.step();
|
||||
}
|
||||
break;
|
||||
case SDIV:
|
||||
break;
|
||||
case MOD:
|
||||
break;
|
||||
case SMOD:
|
||||
break;
|
||||
case SDIV:{
|
||||
|
||||
DataWord word1 = program.stackPop();
|
||||
DataWord word2 = program.stackPop();
|
||||
word1.sDiv(word2);
|
||||
program.stackPush(word1);
|
||||
program.step();
|
||||
}
|
||||
break;
|
||||
case MOD:{
|
||||
|
||||
DataWord word1 = program.stackPop();
|
||||
DataWord word2 = program.stackPop();
|
||||
word1.mod(word2);
|
||||
program.stackPush(word1);
|
||||
program.step();
|
||||
}
|
||||
break;
|
||||
case SMOD:{
|
||||
|
||||
DataWord word1 = program.stackPop();
|
||||
DataWord word2 = program.stackPop();
|
||||
word1.sMod(word2);
|
||||
program.stackPush(word1);
|
||||
program.step();
|
||||
}
|
||||
break;
|
||||
case EXP:{
|
||||
|
||||
DataWord word1 = program.stackPop();
|
||||
|
@ -133,6 +155,8 @@ public class VM {
|
|||
}
|
||||
break;
|
||||
case LT:{
|
||||
|
||||
// todo: can be improved by not using BigInteger
|
||||
DataWord word1 = program.stackPop();
|
||||
DataWord word2 = program.stackPop();
|
||||
if (word1.value().compareTo(word2.value()) == -1){
|
||||
|
@ -145,11 +169,37 @@ public class VM {
|
|||
program.step();
|
||||
}
|
||||
break;
|
||||
case SLT:
|
||||
break;
|
||||
case SGT:
|
||||
break;
|
||||
case SLT:{
|
||||
|
||||
// todo: can be improved by not using BigInteger
|
||||
DataWord word1 = program.stackPop();
|
||||
DataWord word2 = program.stackPop();
|
||||
if (word1.sValue().compareTo(word2.sValue()) == -1){
|
||||
word1.and(DataWord.ZERO);
|
||||
word1.getData()[31] = 1;
|
||||
} else {
|
||||
word1.and(DataWord.ZERO);
|
||||
}
|
||||
program.stackPush(word1);
|
||||
program.step();
|
||||
}break;
|
||||
case SGT:{
|
||||
|
||||
// todo: can be improved by not using BigInteger
|
||||
DataWord word1 = program.stackPop();
|
||||
DataWord word2 = program.stackPop();
|
||||
if (word1.sValue().compareTo(word2.sValue()) == 1){
|
||||
word1.and(DataWord.ZERO);
|
||||
word1.getData()[31] = 1;
|
||||
} else {
|
||||
word1.and(DataWord.ZERO);
|
||||
}
|
||||
program.stackPush(word1);
|
||||
program.step();
|
||||
}break;
|
||||
case GT:{
|
||||
|
||||
// todo: can be improved by not using BigInteger
|
||||
DataWord word1 = program.stackPop();
|
||||
DataWord word2 = program.stackPop();
|
||||
if (word1.value().compareTo(word2.value()) == 1){
|
||||
|
@ -418,7 +468,16 @@ public class VM {
|
|||
DataWord addr = program.stackPop();
|
||||
DataWord value = program.stackPop();
|
||||
|
||||
// for gas calculations [YP 9.2]
|
||||
DataWord oldValue = program.storageLoad(addr);
|
||||
program.storageSave(addr, value);
|
||||
if (oldValue == null && !value.isZero()){
|
||||
program.spendGas(GasLedger.G_SSTORE * 2);
|
||||
} else if (oldValue != null && value.isZero()){
|
||||
program.spendGas(GasLedger.G_SSTORE * 0);
|
||||
} else
|
||||
program.spendGas(GasLedger.G_SSTORE);
|
||||
|
||||
program.step();
|
||||
}
|
||||
break;
|
||||
|
@ -456,38 +515,10 @@ public class VM {
|
|||
case GAS:
|
||||
break;
|
||||
|
||||
case PUSH1:
|
||||
case PUSH2:
|
||||
case PUSH3:
|
||||
case PUSH4:
|
||||
case PUSH5:
|
||||
case PUSH6:
|
||||
case PUSH7:
|
||||
case PUSH8:
|
||||
case PUSH9:
|
||||
case PUSH10:
|
||||
case PUSH11:
|
||||
case PUSH12:
|
||||
case PUSH13:
|
||||
case PUSH14:
|
||||
case PUSH15:
|
||||
case PUSH16:
|
||||
case PUSH17:
|
||||
case PUSH18:
|
||||
case PUSH19:
|
||||
case PUSH20:
|
||||
case PUSH21:
|
||||
case PUSH22:
|
||||
case PUSH23:
|
||||
case PUSH24:
|
||||
case PUSH25:
|
||||
case PUSH26:
|
||||
case PUSH27:
|
||||
case PUSH28:
|
||||
case PUSH29:
|
||||
case PUSH30:
|
||||
case PUSH31:
|
||||
case PUSH32:{
|
||||
case PUSH1: case PUSH2: case PUSH3: case PUSH4: case PUSH5: case PUSH6: case PUSH7: case PUSH8:
|
||||
case PUSH9: case PUSH10: case PUSH11: case PUSH12: case PUSH13: case PUSH14: case PUSH15: case PUSH16:
|
||||
case PUSH17: case PUSH18: case PUSH19: case PUSH20: case PUSH21: case PUSH22: case PUSH23: case PUSH24:
|
||||
case PUSH25: case PUSH26: case PUSH27: case PUSH28: case PUSH29: case PUSH30: case PUSH31: case PUSH32:{
|
||||
|
||||
program.step();
|
||||
int nPush = op - PUSH1.val() + 1;
|
||||
|
@ -521,7 +552,9 @@ public class VM {
|
|||
default:{
|
||||
}
|
||||
|
||||
|
||||
// memory gas calc
|
||||
int newMemSize = program.getMemSize();
|
||||
program.spendGas(GasLedger.G_MEMORY * (newMemSize - oldMemSize) /32);
|
||||
}
|
||||
program.fullTrace();
|
||||
} catch (RuntimeException e) {
|
||||
|
|
|
@ -15,7 +15,6 @@ import static org.junit.Assert.fail;
|
|||
|
||||
public class VMTest {
|
||||
|
||||
|
||||
@Test // PUSH1 OP
|
||||
public void testPUSH1(){
|
||||
|
||||
|
@ -817,6 +816,73 @@ public class VMTest {
|
|||
}
|
||||
|
||||
|
||||
@Test // SGT OP
|
||||
public void testSGT_1(){
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("600160020D"), new ProgramInvokeMockImpl());
|
||||
String expected = "0000000000000000000000000000000000000000000000000000000000000001";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // SGT OP
|
||||
public void testSGT_2(){
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("7F000000000000000000000000000000000000000000000000000000000000001E" + // 30
|
||||
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56" + // -170
|
||||
"0D"), new ProgramInvokeMockImpl());
|
||||
|
||||
String expected = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // SGT OP
|
||||
public void testSGT_3(){
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56" + // -170
|
||||
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57" + // -169
|
||||
"0D"), new ProgramInvokeMockImpl());
|
||||
|
||||
String expected = "0000000000000000000000000000000000000000000000000000000000000001";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // SGT OP mal
|
||||
public void testSGT_4(){
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56" + // -170
|
||||
"0D"), new ProgramInvokeMockImpl());
|
||||
try {
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
} catch (RuntimeException e) {
|
||||
assertTrue(program.isStopped());
|
||||
return;
|
||||
}
|
||||
fail();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test // LT OP
|
||||
public void testLT_1(){
|
||||
|
||||
|
@ -876,6 +942,74 @@ public class VMTest {
|
|||
}
|
||||
|
||||
|
||||
@Test // SLT OP
|
||||
public void testSLT_1(){
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("600160020C"), new ProgramInvokeMockImpl());
|
||||
String expected = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // SLT OP
|
||||
public void testSLT_2(){
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("7F000000000000000000000000000000000000000000000000000000000000001E" + // 30
|
||||
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56" + // -170
|
||||
"0C"), new ProgramInvokeMockImpl());
|
||||
|
||||
String expected = "0000000000000000000000000000000000000000000000000000000000000001";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // SLT OP
|
||||
public void testSLT_3(){
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56" + // -170
|
||||
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57" + // -169
|
||||
"0C"), new ProgramInvokeMockImpl());
|
||||
|
||||
String expected = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // SLT OP mal
|
||||
public void testSLT_4(){
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56" + // -170
|
||||
"0D"), new ProgramInvokeMockImpl());
|
||||
try {
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
} catch (RuntimeException e) {
|
||||
assertTrue(program.isStopped());
|
||||
return;
|
||||
}
|
||||
fail();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test // NEG OP
|
||||
public void testNEG_1(){
|
||||
|
||||
|
@ -1743,6 +1877,7 @@ public class VMTest {
|
|||
assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase());
|
||||
}
|
||||
|
||||
|
||||
@Test // DIV OP
|
||||
public void testDIV_5(){
|
||||
|
||||
|
@ -1774,6 +1909,70 @@ public class VMTest {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Test // SDIV OP
|
||||
public void testSDIV_1(){
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("6103E87FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC1805"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // SDIV OP
|
||||
public void testSDIV_2(){
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("60FF60FF05"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000000001";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // SDIV OP
|
||||
public void testSDIV_3(){
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("600060FF05"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase());
|
||||
}
|
||||
|
||||
|
||||
@Test // SDIV OP mal
|
||||
public void testSDIV_4(){
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("60FF05"), new ProgramInvokeMockImpl());
|
||||
|
||||
try {
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
} catch (RuntimeException e) {
|
||||
assertTrue(program.isStopped());
|
||||
return;
|
||||
}
|
||||
fail();
|
||||
}
|
||||
|
||||
|
||||
@Test // SUB OP
|
||||
public void testSUB_1(){
|
||||
|
||||
|
@ -2480,6 +2679,128 @@ public class VMTest {
|
|||
}
|
||||
|
||||
|
||||
@Test // MOD OP
|
||||
public void testMOD_1(){
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("6003600406"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000000001";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // MOD OP
|
||||
public void testMOD_2(){
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("61012C6101F406"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "00000000000000000000000000000000000000000000000000000000000000C8";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // MOD OP
|
||||
public void testMOD_3(){
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("6004600206"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000000002";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase());
|
||||
}
|
||||
|
||||
|
||||
@Test // MOD OP mal
|
||||
public void testMOD_4(){
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("600406"), new ProgramInvokeMockImpl());
|
||||
|
||||
try {
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
} catch (RuntimeException e) {
|
||||
assertTrue(program.isStopped());
|
||||
return;
|
||||
}
|
||||
fail();
|
||||
}
|
||||
|
||||
@Test // SMOD OP
|
||||
public void testSMOD_1(){
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("6003600407"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000000001";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // SMOD OP
|
||||
public void testSMOD_2(){
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2" + // -30
|
||||
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56" + // -170
|
||||
"07"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase());
|
||||
}
|
||||
|
||||
|
||||
@Test // SMOD OP
|
||||
public void testSMOD_3(){
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("7F000000000000000000000000000000000000000000000000000000000000001E" + // 30
|
||||
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF56" + // -170
|
||||
"07"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "000000000000000000000000000000000000000000000000000000000000000A";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.data).toUpperCase());
|
||||
}
|
||||
|
||||
|
||||
@Test // SMOD OP mal
|
||||
public void testSMOD_4(){
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("7F000000000000000000000000000000000000000000000000000000000000001E" + // 30
|
||||
"07"), new ProgramInvokeMockImpl());
|
||||
try {
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
} catch (Exception e) {
|
||||
assertTrue(program.isStopped());
|
||||
return;
|
||||
}
|
||||
fail();
|
||||
}
|
||||
|
||||
/* TEST CASE LIST END */
|
||||
|
||||
|
@ -2498,19 +2819,18 @@ public class VMTest {
|
|||
}
|
||||
|
||||
|
||||
// todo: add gas expeted and calculated to all test cases
|
||||
// todo: considering: G_TXDATA + G_TRANSACTION
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* todo:
|
||||
*
|
||||
* 1) SDIV
|
||||
* 2) MOD
|
||||
* 3) SMOD
|
||||
* 4) SLT
|
||||
* 5) SGT
|
||||
|
||||
|
||||
* 15) PREVHASH:
|
||||
* 16) COINBASE:
|
||||
* 17) TIMESTAMP:
|
||||
|
@ -2524,7 +2844,7 @@ public class VMTest {
|
|||
* 22) CREATE:
|
||||
* 23) CALL:
|
||||
*
|
||||
* 24) SUICIDE:
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue