Implement ADDMOD and MULMOD with unit tests
This commit is contained in:
parent
0f8b51158a
commit
332707df0f
|
@ -340,22 +340,44 @@ public class Program {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* That method implement internal calls
|
||||
* and code invocations
|
||||
* That method implement internal code invocations.
|
||||
*
|
||||
* Instead of immediately calling it adds the call
|
||||
* to a post-queue, to be executed after everything else
|
||||
* (including prior-created posts) within the scope
|
||||
* of that transaction execution is executed.
|
||||
*
|
||||
* @param gas - gas to pay for the call, remaining gas will be refunded to the caller
|
||||
* @param toAddressDW - address to call
|
||||
* @param storageAddressDW - address of the storage to use
|
||||
* @param endowmentValue - the value that can be transfer along with the code execution
|
||||
* @param inDataOffs - start of memory to be input data to the call
|
||||
* @param inDataSize - size of memory to be input data to the call
|
||||
*/
|
||||
public void postToAddress(DataWord gas, DataWord toAddressDW, DataWord storageAddressDW,
|
||||
DataWord endowmentValue, DataWord inDataOffs, DataWord inDataSize) {
|
||||
// TODO implement code
|
||||
}
|
||||
|
||||
/**
|
||||
* That method implement internal code invocations
|
||||
*
|
||||
* @param gas - gas to pay for the call, remaining gas will be refunded to the caller
|
||||
* @param toAddressDW - address to call
|
||||
* @param storageAddressDW - address of the storage to use
|
||||
* @param endowmentValue - the value that can be transfer along with the code execution
|
||||
* @param inDataOffs - start of memory to be input data to the call
|
||||
* @param inDataSize - size of memory to be input data to the call
|
||||
* @param outDataOffs - start of memory to be output of the call
|
||||
* @param outDataSize - size of memory to be output data to the call
|
||||
*/
|
||||
public void callToAddress(DataWord gas, DataWord toAddressDW, DataWord endowmentValue,
|
||||
public void callToAddress(DataWord gas, DataWord toAddressDW, DataWord storageAddressDW, DataWord endowmentValue,
|
||||
DataWord inDataOffs, DataWord inDataSize,DataWord outDataOffs, DataWord outDataSize) {
|
||||
|
||||
// TODO: update code for CALLSTATELESS
|
||||
|
||||
ByteBuffer data = memoryChunk(inDataOffs, inDataSize);
|
||||
|
||||
// FETCH THE SAVED STORAGE
|
||||
|
|
|
@ -144,7 +144,7 @@ public class VM {
|
|||
program.stackRequire(3);
|
||||
newMemSize = stack.peek().value().add(stack.get(stack.size()-3).value());
|
||||
break;
|
||||
case CALL:
|
||||
case CALL: case CALLSTATELESS:
|
||||
program.stackRequire(7);
|
||||
gasCost = GasCost.CALL;
|
||||
BigInteger callGasWord = stack.get(stack.size()-1).value();
|
||||
|
@ -156,12 +156,6 @@ public class VM {
|
|||
BigInteger y = stack.get(stack.size()-6).value().add(stack.get(stack.size()-7).value()); // out offset+size
|
||||
newMemSize = x.max(y);
|
||||
break;
|
||||
case CALLSTATELESS:
|
||||
program.stackRequire(7);
|
||||
// TODO
|
||||
// runGas = c_callGas + m_stack[m_stack.size() - 1];
|
||||
// newTempSize = std::max(memNeed(m_stack[m_stack.size() - 6], m_stack[m_stack.size() - 7]), memNeed(m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5]));
|
||||
break;
|
||||
case POST:
|
||||
program.stackRequire(5);
|
||||
// TODO
|
||||
|
@ -478,12 +472,18 @@ public class VM {
|
|||
program.step();
|
||||
} break;
|
||||
case ADDMOD:{
|
||||
program.stackRequire(3);
|
||||
// TODO: Implement new opcodes
|
||||
program.stackRequire(3);
|
||||
DataWord word1 = program.stackPop();
|
||||
word1.add(program.stackPop());
|
||||
word1.mod(program.stackPop());
|
||||
program.stackPush(word1);
|
||||
} break;
|
||||
case MULMOD:{
|
||||
program.stackRequire(3);
|
||||
// TODO: Implement new opcodes
|
||||
program.stackRequire(3);
|
||||
DataWord word1 = program.stackPop();
|
||||
word1.mul(program.stackPop());
|
||||
word1.mod(program.stackPop());
|
||||
program.stackPush(word1);
|
||||
} break;
|
||||
|
||||
/**
|
||||
|
@ -862,7 +862,7 @@ public class VM {
|
|||
|
||||
program.step();
|
||||
} break;
|
||||
case CALL: {
|
||||
case CALL: case CALLSTATELESS: {
|
||||
program.stackRequire(7);
|
||||
DataWord gas = program.stackPop();
|
||||
DataWord toAddress = program.stackPop();
|
||||
|
@ -885,16 +885,35 @@ public class VM {
|
|||
program.invokeData.getCallDeep(), hint);
|
||||
}
|
||||
|
||||
program.callToAddress(gas, toAddress, value, inDataOffs, inDataSize, outDataOffs, outDataSize);
|
||||
program.callToAddress(gas, toAddress, op.equals(CALL) ? toAddress
|
||||
: program.getOwnerAddress(), value, inDataOffs,
|
||||
inDataSize, outDataOffs, outDataSize);
|
||||
|
||||
program.step();
|
||||
} break;
|
||||
case POST:{
|
||||
program.stackRequire(5);
|
||||
// TODO: Implement POST execution
|
||||
} break;
|
||||
case CALLSTATELESS:{
|
||||
// TODO: Implement CALLSTATELESS (almost same as CALL)
|
||||
DataWord gas = program.stackPop();
|
||||
DataWord toAddress = program.stackPop();
|
||||
DataWord value = program.stackPop();
|
||||
|
||||
DataWord inDataOffs = program.stackPop();
|
||||
DataWord inDataSize = program.stackPop();
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
hint = "addr: " + Hex.toHexString(toAddress.getLast20Bytes())
|
||||
+ " gas: " + gas.shortHex()
|
||||
+ " inOff: " + inDataOffs.shortHex()
|
||||
+ " inSize: " + inDataSize.shortHex();
|
||||
logger.info(logString, program.getPC(),
|
||||
String.format("%-12s", op.name()),
|
||||
program.getGas().value(),
|
||||
program.invokeData.getCallDeep(), hint);
|
||||
}
|
||||
|
||||
program.postToAddress(gas, toAddress, toAddress, value, inDataOffs, inDataSize);
|
||||
|
||||
program.step();
|
||||
} break;
|
||||
case RETURN:{
|
||||
program.stackRequire(2);
|
||||
|
|
|
@ -1177,7 +1177,7 @@ public class VMTest {
|
|||
*
|
||||
* @param n in DUPn
|
||||
*/
|
||||
public void testDUPN_1(int n) {
|
||||
private void testDUPN_1(int n) {
|
||||
|
||||
VM vm = new VM();
|
||||
byte operation = (byte) (OpCode.DUP1.val() + n - 1);
|
||||
|
@ -1218,7 +1218,7 @@ public class VMTest {
|
|||
@Test // SWAP1...SWAP16 OP
|
||||
public void testSWAPS() {
|
||||
for (int i = 1; i < 17; i++) {
|
||||
testSWAPN(i);
|
||||
testSWAPN_1(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1227,7 +1227,7 @@ public class VMTest {
|
|||
*
|
||||
* @param n in SWAPn
|
||||
*/
|
||||
public void testSWAPN(int n) {
|
||||
private void testSWAPN_1(int n) {
|
||||
|
||||
VM vm = new VM();
|
||||
byte operation = (byte) (OpCode.SWAP1.val() + n - 1);
|
||||
|
@ -1253,7 +1253,7 @@ public class VMTest {
|
|||
}
|
||||
|
||||
@Test(expected=StackTooSmallException.class) // SWAPN OP mal data
|
||||
public void testSWAPN_3() {
|
||||
public void testSWAPN_2() {
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("90"), new ProgramInvokeMockImpl());
|
||||
|
@ -1845,9 +1845,70 @@ public class VMTest {
|
|||
assertTrue(program.isStopped());
|
||||
}
|
||||
}
|
||||
|
||||
@Test // ADDMOD OP mal
|
||||
public void testADDMOD_1() {
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("60026002600314"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000000001";
|
||||
|
||||
@Test // MULL OP
|
||||
public void testMULL_1() {
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
program.getResult().getRepository().close();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // ADDMOD OP
|
||||
public void testADDMOD_2() {
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("611000600261100214"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000000004";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
program.getResult().getRepository().close();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // ADDMOD OP
|
||||
public void testADDMOD_3() {
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("61100265123456789009600214"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "000000000000000000000000000000000000000000000000000000000000093B";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
program.getResult().getRepository().close();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||
}
|
||||
|
||||
@Test(expected=StackTooSmallException.class) // ADDMOD OP mal
|
||||
public void testADDMOD_4() {
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("61123414"), new ProgramInvokeMockImpl());
|
||||
try {
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
} finally {
|
||||
program.getResult().getRepository().close();
|
||||
assertTrue(program.isStopped());
|
||||
}
|
||||
}
|
||||
|
||||
@Test // MUL OP
|
||||
public void testMUL_1() {
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("6003600202"), new ProgramInvokeMockImpl());
|
||||
|
@ -1862,8 +1923,8 @@ public class VMTest {
|
|||
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // MULL OP
|
||||
public void testMULL_2() {
|
||||
@Test // MUL OP
|
||||
public void testMUL_2() {
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("62222222600302"), new ProgramInvokeMockImpl());
|
||||
|
@ -1878,8 +1939,8 @@ public class VMTest {
|
|||
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // MULL OP
|
||||
public void testMULL_3() {
|
||||
@Test // MUL OP
|
||||
public void testMUL_3() {
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("622222226233333302"), new ProgramInvokeMockImpl());
|
||||
|
@ -1894,8 +1955,8 @@ public class VMTest {
|
|||
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||
}
|
||||
|
||||
@Test(expected=StackTooSmallException.class) // MULL OP mal
|
||||
public void testMULL_4() {
|
||||
@Test(expected=StackTooSmallException.class) // MUL OP mal
|
||||
public void testMUL_4() {
|
||||
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("600102"), new ProgramInvokeMockImpl());
|
||||
|
@ -1907,6 +1968,67 @@ public class VMTest {
|
|||
assertTrue(program.isStopped());
|
||||
}
|
||||
}
|
||||
|
||||
@Test // MULMOD OP
|
||||
public void testMULMOD_1() {
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("60036002600415"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000000002";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
program.getResult().getRepository().close();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // MULMOD OP
|
||||
public void testMULMOD_2() {
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("622222226003600415"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "000000000000000000000000000000000000000000000000000000000000000C";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
program.getResult().getRepository().close();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||
}
|
||||
|
||||
@Test // MULMOD OP
|
||||
public void testMULMOD_3() {
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("62222222623333336244444415"), new ProgramInvokeMockImpl());
|
||||
String s_expected_1 = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
DataWord item1 = program.stack.pop();
|
||||
program.getResult().getRepository().close();
|
||||
assertEquals(s_expected_1, Hex.toHexString(item1.getData()).toUpperCase());
|
||||
}
|
||||
|
||||
@Test(expected=StackTooSmallException.class) // MULMOD OP mal
|
||||
public void testMULMOD_4() {
|
||||
VM vm = new VM();
|
||||
Program program = new Program(Hex.decode("600115"), new ProgramInvokeMockImpl());
|
||||
try {
|
||||
vm.step(program);
|
||||
vm.step(program);
|
||||
} finally {
|
||||
program.getResult().getRepository().close();
|
||||
assertTrue(program.isStopped());
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DIV OP
|
||||
public void testDIV_1() {
|
||||
|
@ -2834,14 +2956,14 @@ public class VMTest {
|
|||
program.getResult().getRepository().close();
|
||||
assertTrue(program.isStopped());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@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);
|
||||
|
|
Loading…
Reference in New Issue