CALL op with in/out data
+ support for return + VMComplexText test3 demonstrates the return applied
This commit is contained in:
parent
d2676eda92
commit
0b02376c17
|
@ -4,15 +4,16 @@
|
|||
----------------
|
||||
|
||||
- [x] **VM execution:** support CALL op
|
||||
- [ ] **VM execution:** support CALL op with in/out data
|
||||
- [x] **VM execution:** support CALL op with in/out data
|
||||
- [ ] **VM execution:** support CREATE op
|
||||
- [ ] **VM execution:** SUICIDE op adjust
|
||||
- [ ] **ProgramPlayDialog** support internal calls
|
||||
- [ ] **Build:** extract core module and studio application
|
||||
- [ ] **Performance:** BigInteger math change for constant arrays implementation
|
||||
economy for memory allocation
|
||||
- [ ] **Command Line:** add the headless run option
|
||||
- [ ] **Testing by JSON files:** follow cpp client performs test case by getting json file contains the test describe
|
||||
- [ ] Serpent new syntax:
|
||||
- [ ] **SerpentCompiler** Serpent new syntax:
|
||||
(@> @< @/ @%) - unsigned operations
|
||||
> < / % - default are all signed operations
|
||||
+= -= *= /= %= @/= @%= - short form operations
|
||||
|
@ -23,7 +24,9 @@ share - code section
|
|||
##### UnitTest:
|
||||
----------------
|
||||
|
||||
- [ ] **VM complex: CALL testing for in/out arrays
|
||||
- [ ] **VM complex: CREATE testing
|
||||
- [x] **VM complex:** CALL testing for in arrays
|
||||
- [x] **VM complex:** CALL testing for out result
|
||||
- [ ] **VM complex:** CREATE testing
|
||||
- [ ] **VM complex:** SUICIDE testing
|
||||
- [ ] **WorldManager** apply transactions
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ public class ProgramPlayDialog extends JPanel implements ActionListener,
|
|||
//Schedule a job for the event-dispatching thread:
|
||||
//creating and showing this application's GUI.
|
||||
|
||||
String asmCode ="0 31 MSTORE8 224 MSIZE 224 MSIZE MSTORE 0 192 MSIZE ADD MSTORE8 96 MSIZE 32 ADD MSIZE DUP 32 ADD 11 SWAP MSTORE DUP 64 ADD 22 SWAP MSTORE DUP 96 ADD 33 SWAP MSTORE 128 SWAP MSTORE 0 752278364205682983151548199104072833112320979438 1000 CALL 32 0 MUL 160 ADD 32 ADD MLOAD 0 MSTORE";
|
||||
String asmCode ="11 0 MSTORE 22 32 MSTORE 33 64 MSTORE 44 96 MSTORE 55 128 MSTORE 66 160 MSTORE 192 0 RETURN";
|
||||
final byte[] code = SerpentCompiler.compileAssemblyToMachine(asmCode);
|
||||
|
||||
|
||||
|
|
|
@ -286,9 +286,9 @@ public class WorldManager {
|
|||
|
||||
// Save the code created by init
|
||||
byte[] bodyCode = null;
|
||||
if (result.gethReturn() != null){
|
||||
if (result.getHReturn() != null){
|
||||
|
||||
bodyCode = result.gethReturn().array();
|
||||
bodyCode = result.getHReturn().array();
|
||||
}
|
||||
|
||||
BigInteger gasPrice =
|
||||
|
|
|
@ -323,9 +323,20 @@ public class Program {
|
|||
return;
|
||||
}
|
||||
|
||||
// todo: apply results: result.gethReturn()
|
||||
// todo: if there is out specified place hReturn on the out
|
||||
// 3. APPLY RESULTS: result.getHReturn() into out_memory allocated
|
||||
ByteBuffer buffer = result.getHReturn();
|
||||
if (buffer != null){
|
||||
|
||||
int retSize = buffer.array().length;
|
||||
int allocSize = outDataSize.intValue();
|
||||
if (retSize > allocSize){
|
||||
|
||||
byte[] outArray = Arrays.copyOf(buffer.array(), allocSize );
|
||||
this.memorySave(outArray, buffer.array());
|
||||
} else{
|
||||
this.memorySave(outDataOffs.getData(), buffer.array());
|
||||
}
|
||||
}
|
||||
|
||||
detailDB.commitTrack();
|
||||
chainDB.commitTrack();
|
||||
|
@ -333,6 +344,7 @@ public class Program {
|
|||
stackPush(new DataWord(1));
|
||||
|
||||
// the gas spent in any internal outcome
|
||||
// even if execution was halted by an exception
|
||||
spendGas(result.getGasUsed(), " 'Total for CALL run' ");
|
||||
logger.info("The usage of the gas in external call updated", result.getGasUsed());
|
||||
|
||||
|
@ -536,8 +548,8 @@ public class Program {
|
|||
globalOutput.append(" -- MEMORY -- ").append(memoryData).append("\n");
|
||||
globalOutput.append(" -- STORAGE -- ").append(storageData).append("\n");
|
||||
|
||||
if (result.gethReturn() != null){
|
||||
globalOutput.append("\n HReturn: ").append(Hex.toHexString(result.gethReturn().array()));
|
||||
if (result.getHReturn() != null){
|
||||
globalOutput.append("\n HReturn: ").append(Hex.toHexString(result.getHReturn().array()));
|
||||
}
|
||||
|
||||
// soffisticated assumption that msg.data != codedata
|
||||
|
|
|
@ -32,7 +32,7 @@ public class ProgramResult {
|
|||
this.hReturn.put(hReturn);
|
||||
}
|
||||
|
||||
public ByteBuffer gethReturn() {
|
||||
public ByteBuffer getHReturn() {
|
||||
return hReturn;
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ public class VMComplexTest {
|
|||
|
||||
|
||||
|
||||
@Test // contract call recursive with data
|
||||
@Test // contractB call contractA with data to storage
|
||||
public void test2(){
|
||||
|
||||
/**
|
||||
|
@ -216,10 +216,126 @@ public class VMComplexTest {
|
|||
assertEquals(expectedVal_1, value_1.longValue());
|
||||
assertEquals(expectedVal_2, value_2.longValue());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test // contractB call contractA with return expectation
|
||||
public void test3(){
|
||||
|
||||
/**
|
||||
* #The code will run
|
||||
* ------------------
|
||||
|
||||
contract A: 77045e71a7a2c50903d88e564cd72fab11e82051
|
||||
---------------
|
||||
|
||||
a = 11
|
||||
b = 22
|
||||
c = 33
|
||||
d = 44
|
||||
e = 55
|
||||
f = 66
|
||||
|
||||
[asm 192 0 RETURN asm]
|
||||
|
||||
|
||||
|
||||
contract B: 83c5541a6c8d2dbad642f385d8d06ca9b6c731ee
|
||||
-----------
|
||||
a = msg((tx.gas / 10 * 8), 0x77045e71a7a2c50903d88e564cd72fab11e82051, 0, [11, 22, 33], 3, 6)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
long expectedVal_1 = 11;
|
||||
long expectedVal_2 = 22;
|
||||
long expectedVal_3 = 33;
|
||||
long expectedVal_4 = 44;
|
||||
long expectedVal_5 = 55;
|
||||
long expectedVal_6 = 66;
|
||||
|
||||
// Set contract into Database
|
||||
String callerAddr = "cd2a3d9f938e13cd947ec05abc7fe734df8dd826";
|
||||
|
||||
String contractA_addr = "77045e71a7a2c50903d88e564cd72fab11e82051";
|
||||
String contractB_addr = "83c5541a6c8d2dbad642f385d8d06ca9b6c731ee";
|
||||
|
||||
String code_a = "600b60005460166020546021604054602c6060546037608054604260a05460c06000f2";
|
||||
String code_b = "6000601f5560e05b60e05b54600060c05b015560605b6020015b51602001600b5254516040016016525451606001602152546080525460007377045e71a7a2c50903d88e564cd72fab11e820516103e8f1602060000260a00160200153600054";
|
||||
|
||||
byte[] caller_addr_bytes = Hex.decode(callerAddr);
|
||||
|
||||
byte[] contractA_addr_bytes = Hex.decode(contractA_addr);
|
||||
byte[] codeA = Hex.decode(code_a);
|
||||
byte[] codeA_Key = HashUtil.sha3(codeA);
|
||||
AccountState accountState_a = new AccountState();
|
||||
accountState_a.setCodeHash(codeA_Key);
|
||||
WorldManager.instance.worldState.update(contractA_addr_bytes, accountState_a.getEncoded());
|
||||
|
||||
byte[] contractB_addr_bytes = Hex.decode(contractB_addr);
|
||||
byte[] codeB = Hex.decode(code_b);
|
||||
byte[] codeB_Key = HashUtil.sha3(codeB);
|
||||
AccountState accountState_b = new AccountState();
|
||||
accountState_b.setCodeHash(codeB_Key);
|
||||
WorldManager.instance.worldState.update(contractB_addr_bytes, accountState_a.getEncoded());
|
||||
|
||||
AccountState callerAcountState = new AccountState();
|
||||
callerAcountState.addToBalance(new BigInteger("100000000000000000000"));
|
||||
WorldManager.instance.worldState.update(caller_addr_bytes, callerAcountState.getEncoded());
|
||||
|
||||
WorldManager.instance.chainDB.put(codeA_Key, codeA);
|
||||
|
||||
TrackTrie stateDB = new TrackTrie(WorldManager.instance.worldState);
|
||||
TrackDatabase chainDb = new TrackDatabase(WorldManager.instance.chainDB);
|
||||
TrackDatabase detaildDB = new TrackDatabase(WorldManager.instance.detaildDB);
|
||||
|
||||
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
|
||||
pi.setDetaildDB(detaildDB);
|
||||
pi.setChainDb(chainDb);
|
||||
pi.setStateDB(stateDB);
|
||||
pi.setDetails(null);
|
||||
pi.setOwnerAddress(contractB_addr);
|
||||
|
||||
// ****************** //
|
||||
// Play the program //
|
||||
// ****************** //
|
||||
VM vm = new VM();
|
||||
Program program = new Program(codeB, pi);
|
||||
|
||||
try {
|
||||
while(!program.isStopped())
|
||||
vm.step(program);
|
||||
} catch (RuntimeException e) {
|
||||
program.setRuntimeFailure(e);
|
||||
}
|
||||
|
||||
|
||||
System.out.println();
|
||||
System.out.println("============ Results ============");
|
||||
AccountState as =
|
||||
new AccountState(WorldManager.instance.worldState.get(
|
||||
Hex.decode( contractA_addr) ));
|
||||
|
||||
|
||||
System.out.println("*** Used gas: " + program.result.getGasUsed());
|
||||
|
||||
DataWord value1 = program.memoryLoad(new DataWord(32));
|
||||
DataWord value2 = program.memoryLoad(new DataWord(64));
|
||||
DataWord value3 = program.memoryLoad(new DataWord(96));
|
||||
DataWord value4 = program.memoryLoad(new DataWord(128));
|
||||
DataWord value5 = program.memoryLoad(new DataWord(160));
|
||||
DataWord value6 = program.memoryLoad(new DataWord(192));
|
||||
|
||||
assertEquals(expectedVal_1, value1.longValue());
|
||||
assertEquals(expectedVal_2, value2.longValue());
|
||||
assertEquals(expectedVal_3, value3.longValue());
|
||||
assertEquals(expectedVal_4, value4.longValue());
|
||||
assertEquals(expectedVal_5, value5.longValue());
|
||||
assertEquals(expectedVal_6, value6.longValue());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -2141,7 +2141,7 @@ public class VMTest {
|
|||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
assertEquals(s_expected_1, Hex.toHexString(program.getResult().gethReturn().array()).toUpperCase());
|
||||
assertEquals(s_expected_1, Hex.toHexString(program.getResult().getHReturn().array()).toUpperCase());
|
||||
assertTrue(program.stopped);
|
||||
}
|
||||
|
||||
|
@ -2160,7 +2160,7 @@ public class VMTest {
|
|||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
assertEquals(s_expected_1, Hex.toHexString(program.getResult().gethReturn().array()).toUpperCase());
|
||||
assertEquals(s_expected_1, Hex.toHexString(program.getResult().getHReturn().array()).toUpperCase());
|
||||
assertTrue(program.stopped);
|
||||
}
|
||||
|
||||
|
@ -2180,7 +2180,7 @@ public class VMTest {
|
|||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
assertEquals(s_expected_1, Hex.toHexString(program.getResult().gethReturn().array()).toUpperCase());
|
||||
assertEquals(s_expected_1, Hex.toHexString(program.getResult().getHReturn().array()).toUpperCase());
|
||||
assertTrue(program.stopped);
|
||||
}
|
||||
|
||||
|
@ -2201,7 +2201,7 @@ public class VMTest {
|
|||
vm.step(program);
|
||||
vm.step(program);
|
||||
|
||||
assertEquals(s_expected_1, Hex.toHexString(program.getResult().gethReturn().array()).toUpperCase());
|
||||
assertEquals(s_expected_1, Hex.toHexString(program.getResult().getHReturn().array()).toUpperCase());
|
||||
assertTrue(program.stopped);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue