diff --git a/ethereumj-core/src/main/java/org/ethereum/db/ContractDetails.java b/ethereumj-core/src/main/java/org/ethereum/db/ContractDetails.java index 7110d567..ec6a6dd6 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/ContractDetails.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/ContractDetails.java @@ -42,19 +42,35 @@ public class ContractDetails { public void put(DataWord key, DataWord value) { - storageTrie.update(key.getData(), value.getData()); + if (value.equals(DataWord.ZERO)){ - int index = storageKeys.indexOf(key); + storageTrie.delete(key.getData()); - if (index != -1) { - storageKeys.remove(index); - storageValues.remove(index); - } + int index = storageKeys.indexOf(key); + if (index != -1) { + storageKeys.remove(index); + storageValues.remove(index); + } - storageKeys.add(key); - storageValues.add(value); + this.rlpEncoded = null; - this.rlpEncoded = null; + + } else{ + + storageTrie.update(key.getData(), value.getData()); + + int index = storageKeys.indexOf(key); + + if (index != -1) { + storageKeys.remove(index); + storageValues.remove(index); + } + + storageKeys.add(key); + storageValues.add(value); + + this.rlpEncoded = null; + } } public DataWord get(DataWord key) { diff --git a/ethereumj-core/src/main/java/org/ethereum/json/JSONHelper.java b/ethereumj-core/src/main/java/org/ethereum/json/JSONHelper.java index 1b9f9c2e..74101890 100644 --- a/ethereumj-core/src/main/java/org/ethereum/json/JSONHelper.java +++ b/ethereumj-core/src/main/java/org/ethereum/json/JSONHelper.java @@ -5,6 +5,7 @@ import org.json.simple.JSONArray; import org.json.simple.JSONValue; import org.spongycastle.util.encoders.Hex; +import java.math.BigInteger; import java.util.*; /** @@ -26,8 +27,8 @@ public class JSONHelper { Map outMap = new LinkedHashMap(); for (DataWord key : storageKeys) { - outMap.put(Hex.toHexString(key.getNoLeadZeroesData()), - Hex.toHexString(storageMap.get(key).getNoLeadZeroesData())); + outMap.put(Hex.toHexString(key.getData()), + Hex.toHexString(storageMap.get(key).getData())); } String mapString = JSONValue.toJSONString(outMap); @@ -36,7 +37,7 @@ public class JSONHelper { JSONArray orderFields = new JSONArray(); orderFields.add("address: " + Hex.toHexString(address)); orderFields.add(" nonce: " + Hex.toHexString(nonce)); - orderFields.add(" balance: " + Hex.toHexString(balance)); + orderFields.add(" balance: " + new BigInteger(balance).toString()); orderFields.add(" stateRoot: " + (stateRoot == null ? "" : Hex.toHexString(stateRoot))); orderFields.add(" codeHash: " + (codeHash == null ? "" : Hex.toHexString(codeHash))); orderFields.add(" code: " + (code == null ? "" : Hex.toHexString(code))); diff --git a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/AccountState.java b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/AccountState.java index de2daf24..a6ffe60a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/AccountState.java +++ b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/AccountState.java @@ -51,8 +51,7 @@ public class AccountState { for (int i = 0; i < size; ++i){ String keyS = keys[i].toString(); - Object valObject = store.get(keys[i]); - byte[] valBytes = Helper.parseDataArray((JSONArray)valObject); + String valS = store.get(keys[i]).toString(); ByteArrayWrapper key; boolean hexVal = Pattern.matches("0[xX][0-9a-fA-F]+", keyS); @@ -64,8 +63,15 @@ public class AccountState { key = new ByteArrayWrapper( data ); } - ByteArrayWrapper value = - new ByteArrayWrapper(valBytes); + ByteArrayWrapper value; + hexVal = Pattern.matches("0[xX][0-9a-fA-F]+", valS); + if (hexVal){ + value = new ByteArrayWrapper( Hex.decode(valS.substring(2)) ); + } else { + + byte[] data = ByteUtil.bigIntegerToBytes( new BigInteger(valS) ); + value = new ByteArrayWrapper( data ); + } storage.put(key, value); } diff --git a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java index 7af59399..88e47526 100644 --- a/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java +++ b/ethereumj-core/src/main/java/org/ethereum/jsontestsuite/TestRunner.java @@ -143,7 +143,7 @@ public class TestRunner { if (!Arrays.equals(expectedCode, actualCode)){ String output = - String.format("The code result is different. key: [ %s ], expectedCode: [ %s ] is actualCode: [ %s ] ", + String.format("The code result is different. account: [ %s ], expectedCode: [ %s ] is actualCode: [ %s ] ", Hex.toHexString(key.getData()), Hex.toHexString(expectedCode), Hex.toHexString(actualCode)); @@ -298,7 +298,7 @@ public class TestRunner { if (!expectedGas.equals(actualGas)){ String output = - String.format("HReturn is differnt expected hReturn: [ %s ], actual hReturn: [ %s ]", + String.format("Gas usage is differnt expected gas usage: [ %s ], actual gas usage: [ %s ]", expectedGas.toString() , actualGas.toString()); logger.info(output); diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java index e557e9ac..122e7fb2 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java @@ -105,9 +105,6 @@ public class WorldManager { // first of all debit the gas from the issuer BigInteger gasDebit = tx.getTotalGasValueDebit(); - // The coinbase get the gas cost - if (coinbase != null) - repository.addBalance(coinbase, gasDebit); byte[] receiverAddress; @@ -148,7 +145,14 @@ public class WorldManager { Hex.toHexString(senderAddress)); return; } - repository.addBalance(senderAddress, gasDebit.negate()); + + repository.addBalance(senderAddress, gasDebit.negate()); + + // The coinbase get the gas cost + if (coinbase != null) + repository.addBalance(coinbase, gasDebit); + + if (stateLogger.isInfoEnabled()) stateLogger.info( "Before contract execution debit the sender address with gas total cost, " @@ -277,6 +281,7 @@ public class WorldManager { } // delete the marked to die accounts + if (result.getDeleteAccounts() == null) return; for (DataWord address : result.getDeleteAccounts()){ repository.delete(address.getNoLeadZeroesData()); diff --git a/ethereumj-core/src/main/java/org/ethereum/trie/Trie.java b/ethereumj-core/src/main/java/org/ethereum/trie/Trie.java index 56c84b04..644d29a7 100644 --- a/ethereumj-core/src/main/java/org/ethereum/trie/Trie.java +++ b/ethereumj-core/src/main/java/org/ethereum/trie/Trie.java @@ -131,7 +131,7 @@ public class Trie implements TrieFacade{ * @param key */ public void delete(byte[] key) { - delete(Hex.encode(key)); + delete(new String(key)); } /** diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/Program.java b/ethereumj-core/src/main/java/org/ethereum/vm/Program.java index b0afda3b..daf74065 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/Program.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/Program.java @@ -596,7 +596,12 @@ public class Program { logger.debug(" -- STACK -- {}", stackData); logger.debug(" -- MEMORY -- {}", memoryData); logger.debug(" -- STORAGE -- {}\n", storageData); - logger.debug("\n\n Spent Gas: {}", result.getGasUsed()); + logger.debug("\n Spent Gas: [ {} ]/[ {} ]\n Left Gas: [ {} ]\n", + result.getGasUsed(), + invokeData.getGas().longValue(), + getGas().longValue()); + + StringBuilder globalOutput = new StringBuilder("\n"); if (stackData.length() > 0) stackData.append("\n"); diff --git a/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/JSONTestSuiteTest.java b/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/JSONTestSuiteTest.java index bfb77eb3..78c75398 100644 --- a/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/JSONTestSuiteTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/jsontestsuite/JSONTestSuiteTest.java @@ -47,7 +47,7 @@ public class JSONTestSuiteTest { JSONParser parser = new JSONParser(); String accountString = "{'balance':999999999999999852,'nonce':1," + "'code':'0x6000600060006000604a3360c85c03f1'," + - "'storage':{'0xffaa' : [200], '0xffab' : ['0xb2b2b2']}}"; + "'storage':{'0xffaa' : '0xc8', '0xffab' : '0xb2b2b2'}}"; accountString = accountString.replace("'", "\""); JSONObject accountJSONObj = (JSONObject)parser.parse(accountString); @@ -270,6 +270,29 @@ public class JSONTestSuiteTest { Assert.assertTrue(result.size() == 0); } + @Ignore + @Test // TestCase file: vmtest-4.json // + public void test10() throws ParseException, IOException, URISyntaxException { + + URL vmtest = ClassLoader + .getSystemResource("jsontestsuite/vmtest-5.json"); + + File vmTestFile = new File(vmtest.toURI()); + byte[] testData = Files.readAllBytes(vmTestFile.toPath()); + String testSrc = new String(testData); + + JSONParser parser = new JSONParser(); + JSONObject testCaseJSONObj = (JSONObject)parser.parse(testSrc); + + TestSuite testSuite = new TestSuite(testCaseJSONObj); + + TestRunner runner = new TestRunner(); + List result = runner.runTestSuite(testSuite); + + Assert.assertTrue(result.size() == 0); + } + + @Test // testing full suite public void testDirectFromGitHub() throws ParseException { diff --git a/ethereumj-core/src/test/resources/jsontestsuite/vmtest-5.json b/ethereumj-core/src/test/resources/jsontestsuite/vmtest-5.json new file mode 100644 index 00000000..d3d95a24 --- /dev/null +++ b/ethereumj-core/src/test/resources/jsontestsuite/vmtest-5.json @@ -0,0 +1,100 @@ +{ + "namecoin": { + "pre": { + "0000000000000000000000000000000000000000": { + "nonce": 0, + "balance": 1500000000000000000, + "storage": {}, + "code": "" + }, + "82a978b3f5962a5b0957d9ee9eef472ee55b42f1": { + "nonce": 1, + "balance": 1000000000000000000, + "storage": {}, + "code": "" + }, + "c305c901078781c232a2a521c2af7980f8385ee9": { + "nonce": 0, + "balance": 0, + "storage": {}, + "code": "0x600035560f601559600060605460206060f260265860203560003557600160405460206040f2" + } + }, + "exec": { + "origin": "82a978b3f5962a5b0957d9ee9eef472ee55b42f1", + "code": "0x600035560f601559600060605460206060f260265860203560003557600160405460206040f2", + "value": 0, + "address": "c305c901078781c232a2a521c2af7980f8385ee9", + "gas": 10000, + "caller": "82a978b3f5962a5b0957d9ee9eef472ee55b42f1", + "data": "0x000000000000000000000000000000000000000000000000000000000000002d000000000000000000000000000000000000000000000000000000000000004e", + "gasPrice": 1000000000000 + }, + "callcreates": [], + "gas": 9762, + "env": { + "currentTimestamp": 1405011413, + "currentGasLimit": 999023, + "previousHash": "dd9c9abf3aba9a813870dad3addac510dfc98362b9d44206a21865c4c059e38d", + "currentCoinbase": "82a978b3f5962a5b0957d9ee9eef472ee55b42f1", + "currentDifficulty": 4190208, + "currentNumber": 1 + }, + "post": { + "0000000000000000000000000000000000000000": { + "nonce": 0, + "balance": 1500000000000000000, + "storage": {}, + "code": "0x" + }, + "82a978b3f5962a5b0957d9ee9eef472ee55b42f1": { + "nonce": 1, + "balance": 1000000000000000000, + "storage": {}, + "code": "0x" + }, + "c305c901078781c232a2a521c2af7980f8385ee9": { + "nonce": 0, + "balance": 0, + "storage": { + "0x2d": "0x4e" + }, + "code": "0x600035560f601559600060605460206060f260265860203560003557600160405460206040f2" + } + }, + "out": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1 + ] + } +} \ No newline at end of file