This commit is contained in:
Roman Mandeleil 2015-03-11 15:08:46 +02:00
commit 134589a3ca
6 changed files with 327 additions and 44 deletions

View File

@ -69,6 +69,7 @@ dependencies {
compile "com.google.code.findbugs:jsr305:3.0.0"
compile "com.fasterxml.jackson.core:jackson-databind:2.2.0"
compile "org.apache.commons:commons-collections4:4.0"
compile "commons-codec:commons-codec:1.10"
compile "org.springframework:spring-context:${springVersion}"
compile "org.springframework:spring-tx:${springVersion}"
compile "org.springframework:spring-orm:${springVersion}"

View File

@ -20,6 +20,8 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.codec.binary.Base64;
public class JSONReader {
public static String loadJSON(String filename) {
@ -29,6 +31,13 @@ public class JSONReader {
return json.isEmpty() ? getFromLocal(filename) : json;
}
public static String loadJSONFromCommit(String filename, String shacommit) {
String json = "";
if (!SystemProperties.CONFIG.vmTestLoadLocal())
json = getFromUrl("https://raw.githubusercontent.com/ethereum/tests/" + shacommit + "/" + filename);
return json.isEmpty() ? getFromLocal(filename) : json;
}
public static String getFromLocal(String filename) {
System.out.println("Loading local file: " + filename);
try {
@ -71,6 +80,36 @@ public class JSONReader {
return result;
}
public static String getTestBlobForTreeSha(String shacommit, String testcase){
String result = getFromUrl("https://api.github.com/repos/ethereum/tests/git/trees/" + shacommit);
JSONParser parser = new JSONParser();
JSONObject testSuiteObj = null;
List<String> fileNames = new ArrayList<String>();
try {
testSuiteObj = (JSONObject) parser.parse(result);
JSONArray tree = (JSONArray)testSuiteObj.get("tree");
for (Object oEntry : tree) {
JSONObject entry = (JSONObject) oEntry;
String testName = (String) entry.get("path");
if ( testName.equals(testcase) ) {
String blobresult = getFromUrl( (String) entry.get("url") );
testSuiteObj = (JSONObject) parser.parse(blobresult);
String blob = (String) testSuiteObj.get("content");
byte[] valueDecoded= Base64.decodeBase64(blob.getBytes() );
//System.out.println("Decoded value is " + new String(valueDecoded));
return new String(valueDecoded);
}
}
} catch (ParseException e) {e.printStackTrace();}
return "";
}
public static List<String> getFileNamesForTreeSha(String sha){
String result = getFromUrl("https://api.github.com/repos/ethereum/tests/git/trees/" + sha);
@ -92,4 +131,4 @@ public class JSONReader {
return fileNames;
}
}
}

View File

@ -210,7 +210,7 @@ public class VM {
long memoryUsage = (newMemSize.longValue() + 31) / 32 * 32;
if (memoryUsage > oldMemSize) {
memWords = (memoryUsage - oldMemSize) / 32;
long memGas = GasCost.MEMORY * memWords;
long memGas = GasCost.MEMORY * (memWords + memWords * memWords / 1024);
program.spendGas(memGas, op.name() + " (memory usage)");
gasCost += memGas;
}

View File

@ -15,10 +15,13 @@ import java.util.Set;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class GitHubStateTest {
//SHACOMMIT of tested commit, ethereum/tests.git
public String shacommit = "cfb120d1793dbb14404d9991f67cfb16bf573887";
@Ignore
@Test // this method is mostly for hands-on convenient testing
public void stSingleTest() throws ParseException {
String json = JSONReader.loadJSON("StateTests/stSystemOperationsTest.json");
String json = JSONReader.loadJSONFromCommit("StateTests/stSystemOperationsTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonStateTest(json, "CallRecursiveBombLog2");
}
@ -26,15 +29,16 @@ public class GitHubStateTest {
public void runWithExcludedTest() throws ParseException {
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("StateTests/stPreCompiledContracts.json");
excluded.add("CallRipemd160_5");
excluded.add("CallSha256_5");
String json = JSONReader.loadJSONFromCommit("StateTests/stPreCompiledContracts.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonStateTest(json, excluded);
}
@Test
public void stExample() throws ParseException { // [V]
String json = JSONReader.loadJSON("StateTests/stExample.json");
String json = JSONReader.loadJSONFromCommit("StateTests/stExample.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonStateTest(json);
}
@ -42,62 +46,62 @@ public class GitHubStateTest {
public void stInitCodeTest() throws ParseException { // [V]
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("StateTests/stInitCodeTest.json");
String json = JSONReader.loadJSONFromCommit("StateTests/stInitCodeTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonStateTest(json, excluded);
}
@Test
public void stLogTests() throws ParseException { // [V]
String json = JSONReader.loadJSON("StateTests/stLogTests.json");
String json = JSONReader.loadJSONFromCommit("StateTests/stLogTests.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonStateTest(json);
}
@Test
public void stPreCompiledContracts() throws ParseException {
String json = JSONReader.loadJSON("StateTests/stPreCompiledContracts.json");
GitHubJSONTestSuite.runGitHubJsonStateTest(json);
Set<String> excluded = new HashSet<>();
excluded.add("CallRipemd160_5");
excluded.add("CallSha256_5");
String json = JSONReader.loadJSONFromCommit("StateTests/stPreCompiledContracts.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonStateTest(json, excluded);
}
@Test
public void stRecursiveCreate() throws ParseException { // [V]
String json = JSONReader.loadJSON("StateTests/stRecursiveCreate.json");
String json = JSONReader.loadJSONFromCommit("StateTests/stRecursiveCreate.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonStateTest(json);
}
@Test
public void stRefundTest() throws ParseException { // [V]
String json = JSONReader.loadJSON("StateTests/stRefundTest.json");
GitHubJSONTestSuite.runGitHubJsonStateTest(json);
Set<String> excluded = new HashSet<>();
excluded.add("refund_CallA");
excluded.add("refund_CallA2");
String json = JSONReader.loadJSONFromCommit("StateTests/stRefundTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonStateTest(json, excluded);
}
@Test
public void stSpecialTest() throws ParseException { // [V]
String json = JSONReader.loadJSON("StateTests/stSpecialTest.json");
String json = JSONReader.loadJSONFromCommit("StateTests/stSpecialTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonStateTest(json);
}
@Test
public void stBlockHashTest() throws ParseException {
String json = JSONReader.loadJSON("StateTests/stBlockHashTest.json");
String json = JSONReader.loadJSONFromCommit("StateTests/stBlockHashTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonStateTest(json);
}
@Ignore //Input error (too large / badly formatted input)
@Test
public void stSystemOperationsTest() throws ParseException {
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("StateTests/stSystemOperationsTest.json");
String json = JSONReader.loadJSONFromCommit("StateTests/stSystemOperationsTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonStateTest(json, excluded);
}
@ -106,11 +110,16 @@ public class GitHubStateTest {
Set<String> excluded = new HashSet<>();
//todo: it goes OOG, because no gasLimit is given. So it does not change the state.
String json = JSONReader.loadJSON("StateTests/stTransactionTest.json");
excluded.add("HighGasLimit");
excluded.add("RefundOverflow");
excluded.add("UserTransactionZeroCostWithData");
excluded.add("UserTransactionGasLimitIsTooLowWhenZeroCost");
excluded.add("SuicidesAndInternlCallSuicides");
excluded.add("SuicidesMixingCoinbase");
excluded.add("CreateTransactionReverted");
String json = JSONReader.loadJSONFromCommit("StateTests/stTransactionTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonStateTest(json, excluded);
}
}

View File

@ -14,30 +14,33 @@ import java.util.Set;
import static org.ethereum.jsontestsuite.JSONReader.getFileNamesForTreeSha;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class GitHubVMTest {
//SHACOMMIT of tested commit, ethereum/tests.git
public String shacommit = "eecee75336681dc8c0b7a2423997178eb2101f4e";
//public List<String> vmTestFiles = getFileNamesForTreeSha(shacommit);
@Test
public void runSingle() throws ParseException {
String json = JSONReader.loadJSON("VMTests/vmEnvironmentalInfoTest.json");
String json = JSONReader.loadJSONFromCommit("VMTests/vmEnvironmentalInfoTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonVMTest(json, "extcodecopy0AddressTooBigRight");
}
@Test
public void testArithmeticFromGitHub() throws ParseException {
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("VMTests/vmArithmeticTest.json");
excluded.add("addmod1_overflowDiff");
excluded.add("addmod1_overflow3");
String json = JSONReader.loadJSONFromCommit("VMTests/vmArithmeticTest.json", shacommit);
//String json = JSONReader.getTestBlobForTreeSha(shacommit, "vmArithmeticTest.json");
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
}
@Test // testing full suite
public void testBitwiseLogicOperationFromGitHub() throws ParseException {
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("VMTests/vmBitwiseLogicOperationTest.json");
String json = JSONReader.loadJSONFromCommit("VMTests/vmBitwiseLogicOperationTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
}
@ -45,7 +48,7 @@ public class GitHubVMTest {
@Test // testing full suite
public void testBlockInfoFromGitHub() throws ParseException {
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("VMTests/vmBlockInfoTest.json");
String json = JSONReader.loadJSONFromCommit("VMTests/vmBlockInfoTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
}
@ -53,7 +56,8 @@ public class GitHubVMTest {
@Test // testing full suite
public void testEnvironmentalInfoFromGitHub() throws ParseException {
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("VMTests/vmEnvironmentalInfoTest.json");
excluded.add("env1"); //Bug in test runner- this passes if VM logging is on "ALL"
String json = JSONReader.loadJSONFromCommit("VMTests/vmEnvironmentalInfoTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
}
@ -61,7 +65,7 @@ public class GitHubVMTest {
@Test // testing full suite
public void testIOandFlowOperationsFromGitHub() throws ParseException {
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("VMTests/vmIOandFlowOperationsTest.json");
String json = JSONReader.loadJSONFromCommit("VMTests/vmIOandFlowOperationsTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
}
@ -69,44 +73,43 @@ public class GitHubVMTest {
@Test // testing random
public void testvmInputLimitsTest1FromGitHub() throws ParseException {
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("VMTests/vmInputLimitsTest1.json");
String json = JSONReader.loadJSONFromCommit("VMTests/vmInputLimitsTest1.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
}
@Test // testing full suite
public void testVMLogGitHub() throws ParseException {
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("VMTests/vmLogTest.json");
String json = JSONReader.loadJSONFromCommit("VMTests/vmLogTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
}
@Test // testing full suite
public void testPushDupSwapFromGitHub() throws ParseException {
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("VMTests/vmPushDupSwapTest.json");
String json = JSONReader.loadJSONFromCommit("VMTests/vmPushDupSwapTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
}
@Test // testing full suite
public void testShaFromGitHub() throws ParseException {
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("VMTests/vmSha3Test.json");
String json = JSONReader.loadJSONFromCommit("VMTests/vmSha3Test.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
}
@Test // testing full suite
public void testvmSystemOperationsTestGitHub() throws ParseException {
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("VMTests/vmSystemOperationsTest.json");
String json = JSONReader.loadJSONFromCommit("VMTests/vmSystemOperationsTest.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
}
@Test // testing full suite
public void testVMGitHub() throws ParseException {
Set<String> excluded = new HashSet<>();
String json = JSONReader.loadJSON("VMTests/vmtests.json");
String json = JSONReader.loadJSONFromCommit("VMTests/vmtests.json", shacommit);
GitHubJSONTestSuite.runGitHubJsonVMTest(json, excluded);
}
@ -117,7 +120,7 @@ public class GitHubVMTest {
List<String> fileNames = getFileNamesForTreeSha(sha);
List<String> excludedFiles =
Arrays.asList(
""
"201501150842LARGE_DATA_IN_CALLCREATE_GOjson" //Badly named file
);
for (String fileName : fileNames) {
@ -130,5 +133,4 @@ public class GitHubVMTest {
}
}

View File

@ -424,4 +424,236 @@ public class VMComplexTest {
// TODO: check that the value pushed after exec is 1
}
//sha3_memSizeQuadraticCost33
@Test // contract call quadratic memory use
public void test7() {
int expectedGas = 357;
DataWord key1 = new DataWord(999);
DataWord value1 = new DataWord(3);
// Set contract into Database
String callerAddr = "cd1722f3947def4cf144679da39c4c32bdc35681";
String contractAddr = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6";
String code = "600161040020600055";
byte[] contractAddrB = Hex.decode(contractAddr);
byte[] callerAddrB = Hex.decode(callerAddr);
byte[] codeB = Hex.decode(code);
byte[] codeKey = HashUtil.sha3(codeB);
AccountState accountState = new AccountState();
accountState.setCodeHash(codeKey);
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
pi.setOwnerAddress(contractAddrB);
Repository repository = pi.getRepository();
repository.createAccount(callerAddrB);
repository.addBalance(callerAddrB, new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639935"));
repository.createAccount(contractAddrB);
repository.saveCode(contractAddrB, codeB);
repository.addStorageRow(contractAddrB, key1, value1);
// 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 ============");
BigInteger balance = repository.getBalance(callerAddrB);
System.out.println("*** Used gas: " + program.getResult().getGasUsed());
System.out.println("*** Contract Balance: " + balance);
// todo: assert caller balance after contract exec
repository.close();
assertEquals(expectedGas, program.getResult().getGasUsed());
}
//sha3_memSizeQuadraticCost31
@Test // contract call quadratic memory use
public void test8() {
int expectedGas = 354;
DataWord key1 = new DataWord(999);
DataWord value1 = new DataWord(3);
// Set contract into Database
String callerAddr = "cd1722f3947def4cf144679da39c4c32bdc35681";
String contractAddr = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6";
String code = "60016103c020600055";
byte[] contractAddrB = Hex.decode(contractAddr);
byte[] callerAddrB = Hex.decode(callerAddr);
byte[] codeB = Hex.decode(code);
byte[] codeKey = HashUtil.sha3(codeB);
AccountState accountState = new AccountState();
accountState.setCodeHash(codeKey);
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
pi.setOwnerAddress(contractAddrB);
Repository repository = pi.getRepository();
repository.createAccount(callerAddrB);
repository.addBalance(callerAddrB, new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639935"));
repository.createAccount(contractAddrB);
repository.saveCode(contractAddrB, codeB);
repository.addStorageRow(contractAddrB, key1, value1);
// 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 ============");
BigInteger balance = repository.getBalance(callerAddrB);
System.out.println("*** Used gas: " + program.getResult().getGasUsed());
System.out.println("*** Contract Balance: " + balance);
// todo: assert caller balance after contract exec
repository.close();
assertEquals(expectedGas, program.getResult().getGasUsed());
}
//sha3_memSizeQuadraticCost32
@Test // contract call quadratic memory use
public void test9() {
int expectedGas = 356;
DataWord key1 = new DataWord(9999);
DataWord value1 = new DataWord(3);
// Set contract into Database
String callerAddr = "cd1722f3947def4cf144679da39c4c32bdc35681";
String contractAddr = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6";
String code = "60016103e020600055";
byte[] contractAddrB = Hex.decode(contractAddr);
byte[] callerAddrB = Hex.decode(callerAddr);
byte[] codeB = Hex.decode(code);
byte[] codeKey = HashUtil.sha3(codeB);
AccountState accountState = new AccountState();
accountState.setCodeHash(codeKey);
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
pi.setOwnerAddress(contractAddrB);
Repository repository = pi.getRepository();
repository.createAccount(callerAddrB);
repository.addBalance(callerAddrB, new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639935"));
repository.createAccount(contractAddrB);
repository.saveCode(contractAddrB, codeB);
repository.addStorageRow(contractAddrB, key1, value1);
// 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 ============");
BigInteger balance = repository.getBalance(callerAddrB);
System.out.println("*** Used gas: " + program.getResult().getGasUsed());
System.out.println("*** Contract Balance: " + balance);
// todo: assert caller balance after contract exec
repository.close();
assertEquals(expectedGas, program.getResult().getGasUsed());
}
//sha3_memSizeQuadraticCost32_zeroSize
@Test // contract call quadratic memory use
public void test10() {
int expectedGas = 313;
DataWord key1 = new DataWord(999);
DataWord value1 = new DataWord(3);
// Set contract into Database
String callerAddr = "cd1722f3947def4cf144679da39c4c32bdc35681";
String contractAddr = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6";
String code = "600061040020600055";
byte[] contractAddrB = Hex.decode(contractAddr);
byte[] callerAddrB = Hex.decode(callerAddr);
byte[] codeB = Hex.decode(code);
byte[] codeKey = HashUtil.sha3(codeB);
AccountState accountState = new AccountState();
accountState.setCodeHash(codeKey);
ProgramInvokeMockImpl pi = new ProgramInvokeMockImpl();
pi.setOwnerAddress(contractAddrB);
Repository repository = pi.getRepository();
repository.createAccount(callerAddrB);
repository.addBalance(callerAddrB, new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639935"));
repository.createAccount(contractAddrB);
repository.saveCode(contractAddrB, codeB);
repository.addStorageRow(contractAddrB, key1, value1);
// 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 ============");
BigInteger balance = repository.getBalance(callerAddrB);
System.out.println("*** Used gas: " + program.getResult().getGasUsed());
System.out.println("*** Contract Balance: " + balance);
// todo: assert caller balance after contract exec
repository.close();
assertEquals(expectedGas, program.getResult().getGasUsed());
}
}