From c1b8cd3bf9c79b29042ec388f12b86ac72312af1 Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 15:49:34 +0200 Subject: [PATCH 01/13] Add failing Block calc tests and update Denomination enum --- .../src/main/java/org/ethereum/core/Block.java | 13 +++++-------- .../src/main/java/org/ethereum/core/Blockchain.java | 12 +++++++----- .../main/java/org/ethereum/core/Denomination.java | 8 +++++--- .../src/test/java/org/ethereum/core/BlockTest.java | 12 ++++++++++++ 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Block.java b/ethereumj-core/src/main/java/org/ethereum/core/Block.java index f8ce6771..d1fd49f7 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Block.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Block.java @@ -66,9 +66,6 @@ public class Block { this.parsed = true; } - // [parent_hash, uncles_hash, coinbase, state_root, tx_trie_root, - // difficulty, number, minGasPrice, gasLimit, gasUsed, timestamp, - // extradata, nonce] private void parseRLP() { RLPList params = (RLPList) RLP.decode2(rlpEncoded); @@ -294,15 +291,15 @@ public class Block { * likely next period. Conversely, if the period is too large, the difficulty, * and expected time to the next block, is reduced. */ - private boolean isValid() { - boolean isValid = false; + public boolean isValid() { + boolean isValid = true; // verify difficulty meets requirements - isValid = this.getDifficulty() == this.calcDifficulty(); + //isValid = this.getDifficulty() == this.calcDifficulty(); // verify gasLimit meets requirements - isValid = this.getGasLimit() == this.calcGasLimit(); + //isValid = this.getGasLimit() == this.calcGasLimit(); // verify timestamp meets requirements - isValid = this.getTimestamp() > this.getParent().getTimestamp(); +// isValid = this.getTimestamp() > this.getParent().getTimestamp(); return isValid; } diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java b/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java index 2c08d939..b4ef3687 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java @@ -83,11 +83,13 @@ public class Blockchain extends ArrayList { } private void addBlock(Block block) { - this.wallet.processBlock(block); - this.gasPrice = block.getMinGasPrice(); - if(lastBlock == null || block.getNumber() > lastBlock.getNumber()) - this.lastBlock = block; - this.add(block); + if(block.isValid()) { + this.wallet.processBlock(block); + this.gasPrice = block.getMinGasPrice(); + if(lastBlock == null || block.getNumber() > lastBlock.getNumber()) + this.lastBlock = block; + this.add(block); + } } public long getGasPrice() { diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Denomination.java b/ethereumj-core/src/main/java/org/ethereum/core/Denomination.java index 8e2b6b97..2d5fa7c3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Denomination.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Denomination.java @@ -10,15 +10,17 @@ public enum Denomination { SHANNON(newBigInt(9)), SZABO(newBigInt(12)), FINNY(newBigInt(15)), - ETHER(newBigInt(18)); - + ETHER(newBigInt(18)), + EINSTEIN(newBigInt(21)), + DOUGLAS(newBigInt(42)); + private BigInteger amount; private Denomination(BigInteger value) { this.amount = value; } - public BigInteger getDenomination() { + public BigInteger value() { return amount; } diff --git a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java index 2210d050..773af8dc 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java @@ -86,4 +86,16 @@ public class BlockTest { BlocksMessage blockData = new BlocksMessage(rlpList); System.out.println(blockData.toString()); } + + @Test + public void testCalcDifficulty() { + // Block.calcDifficulty() + fail("Yet to be implemented."); + } + + @Test + public void testCalcGasLimit() { + // Block.calcGasLimit() + fail("Yet to be implemented."); + } } \ No newline at end of file From 0a4a030f561bfc18f2e80c0a512b09ed615d52e4 Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 15:49:34 +0200 Subject: [PATCH 02/13] Add failing Block calc tests and update Denomination enum --- .../src/main/java/org/ethereum/core/Block.java | 13 +++++-------- .../src/main/java/org/ethereum/core/Blockchain.java | 12 +++++++----- .../main/java/org/ethereum/core/Denomination.java | 8 +++++--- .../src/test/java/org/ethereum/core/BlockTest.java | 12 ++++++++++++ 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Block.java b/ethereumj-core/src/main/java/org/ethereum/core/Block.java index f8ce6771..d1fd49f7 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Block.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Block.java @@ -66,9 +66,6 @@ public class Block { this.parsed = true; } - // [parent_hash, uncles_hash, coinbase, state_root, tx_trie_root, - // difficulty, number, minGasPrice, gasLimit, gasUsed, timestamp, - // extradata, nonce] private void parseRLP() { RLPList params = (RLPList) RLP.decode2(rlpEncoded); @@ -294,15 +291,15 @@ public class Block { * likely next period. Conversely, if the period is too large, the difficulty, * and expected time to the next block, is reduced. */ - private boolean isValid() { - boolean isValid = false; + public boolean isValid() { + boolean isValid = true; // verify difficulty meets requirements - isValid = this.getDifficulty() == this.calcDifficulty(); + //isValid = this.getDifficulty() == this.calcDifficulty(); // verify gasLimit meets requirements - isValid = this.getGasLimit() == this.calcGasLimit(); + //isValid = this.getGasLimit() == this.calcGasLimit(); // verify timestamp meets requirements - isValid = this.getTimestamp() > this.getParent().getTimestamp(); +// isValid = this.getTimestamp() > this.getParent().getTimestamp(); return isValid; } diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java b/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java index 2c08d939..b4ef3687 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java @@ -83,11 +83,13 @@ public class Blockchain extends ArrayList { } private void addBlock(Block block) { - this.wallet.processBlock(block); - this.gasPrice = block.getMinGasPrice(); - if(lastBlock == null || block.getNumber() > lastBlock.getNumber()) - this.lastBlock = block; - this.add(block); + if(block.isValid()) { + this.wallet.processBlock(block); + this.gasPrice = block.getMinGasPrice(); + if(lastBlock == null || block.getNumber() > lastBlock.getNumber()) + this.lastBlock = block; + this.add(block); + } } public long getGasPrice() { diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Denomination.java b/ethereumj-core/src/main/java/org/ethereum/core/Denomination.java index 8e2b6b97..2d5fa7c3 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Denomination.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Denomination.java @@ -10,15 +10,17 @@ public enum Denomination { SHANNON(newBigInt(9)), SZABO(newBigInt(12)), FINNY(newBigInt(15)), - ETHER(newBigInt(18)); - + ETHER(newBigInt(18)), + EINSTEIN(newBigInt(21)), + DOUGLAS(newBigInt(42)); + private BigInteger amount; private Denomination(BigInteger value) { this.amount = value; } - public BigInteger getDenomination() { + public BigInteger value() { return amount; } diff --git a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java index 2210d050..773af8dc 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java @@ -86,4 +86,16 @@ public class BlockTest { BlocksMessage blockData = new BlocksMessage(rlpList); System.out.println(blockData.toString()); } + + @Test + public void testCalcDifficulty() { + // Block.calcDifficulty() + fail("Yet to be implemented."); + } + + @Test + public void testCalcGasLimit() { + // Block.calcGasLimit() + fail("Yet to be implemented."); + } } \ No newline at end of file From 76175bca905b1ed5e2e7efa5d9eb241d01603fb0 Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 16:13:05 +0200 Subject: [PATCH 03/13] Replace GasLedger with Gas enum class --- .../main/java/org/ethereum/core/Block.java | 4 +- .../src/main/java/org/ethereum/vm/Gas.java | 33 +++++++++++++++ .../main/java/org/ethereum/vm/GasLedger.java | 41 ------------------- .../src/main/java/org/ethereum/vm/VM.java | 21 +++++----- .../java/org/ethereum/core/BlockTest.java | 7 +++- 5 files changed, 53 insertions(+), 53 deletions(-) create mode 100644 ethereumj-core/src/main/java/org/ethereum/vm/Gas.java delete mode 100644 ethereumj-core/src/main/java/org/ethereum/vm/GasLedger.java diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Block.java b/ethereumj-core/src/main/java/org/ethereum/core/Block.java index d1fd49f7..f6b452a0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Block.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Block.java @@ -9,6 +9,8 @@ import org.ethereum.util.RLPElement; import org.ethereum.util.RLPList; import org.spongycastle.util.BigIntegers; +import edu.emory.mathcs.backport.java.util.Arrays; + import java.math.BigInteger; import java.util.ArrayList; import java.util.List; @@ -320,7 +322,7 @@ public class Block { } public byte[] calcDifficulty() { - if (this.header.getParentHash() == null) + if (Arrays.equals(this.header.getParentHash(), Genesis.PARENT_HASH)) return Genesis.DIFFICULTY; else { Block parent = this.getParent(); diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java b/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java new file mode 100644 index 00000000..99bd5724 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java @@ -0,0 +1,33 @@ +package org.ethereum.vm; + +/** + * The fundamental network cost unit. Paid for exclusively by Ether, which is converted + * freely to and from Gas as required. Gas does not exist outside of the internal Ethereum + * computation engine; its price is set by the Transaction and miners are free to + * ignore Transactions whose Gas price is too low. + */ +public enum Gas { + + G_STEP(1), + G_STOP(0), + G_SUICIDE(0), + G_SLOAD(20), + G_SHA3(20), + G_SSTORE(100), + G_BALANCE(20), + G_CREATE(100), + G_CALL(20), + G_MEMORY(1), + G_TXDATA(5), + G_TRANSACTION(500); + + private int cost; + + private Gas(int value) { + this.cost = value; + } + + public int cost() { + return cost; + } +} \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/GasLedger.java b/ethereumj-core/src/main/java/org/ethereum/vm/GasLedger.java deleted file mode 100644 index 314cdcbf..00000000 --- a/ethereumj-core/src/main/java/org/ethereum/vm/GasLedger.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.ethereum.vm; - -import java.util.HashMap; - -/** - * www.ethereumJ.com - * User: Roman Mandeleil - * Created on: 04/06/2014 23:58 - */ - -public class GasLedger { - -/* YP Appendix B. - Gstep 1 Default amount of gas to pay for execution cycle. - Gstop 0 Nothing paid for the STOP operation. - Gsuicide 0 Nothing paid for the SUICIDE operation. - Gsha3 20 Paid for a SHA3 operation. - Gsload 20 Paid for a SLOAD operation. - Gsstore 100 Paid for a normal SSTORE operation (doubled or waived sometimes). - Gbalance 20 Paid for a BALANCE operation. - Gcreate 100 Paid for a CREATE operation. - Gcall 20 Paid for a CALL operation. - Gmemory 1 Paid for every additional word when expanding memory. - Gtxdata 5 Paid for every byte of data or code for a transaction. - Gtransaction 500 Paid for every transaction. - */ - - - public static int G_STEP = 1; - public static int G_STOP = 0; - public static int G_SUICIDE = 0; - public static int G_SLOAD = 20; - public static int G_SHA3 = 20; - public static int G_SSTORE = 100; - public static int G_BALANCE = 20; - public static int G_CREATE = 100; - public static int G_CALL = 20; - public static int G_MEMORY = 1; - public static int G_TXDATA = 5; - public static int G_TRANSACTION = 500; -} diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java index 0c575b7a..712c5321 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java @@ -8,6 +8,7 @@ import java.math.BigInteger; import java.nio.ByteBuffer; import static org.ethereum.vm.OpCode.PUSH1; +import static org.ethereum.vm.Gas.*; /** * www.ethereumJ.com @@ -34,23 +35,23 @@ public class VM { switch (OpCode.code(op)) { case SHA3: - program.spendGas( GasLedger.G_SHA3 ); + program.spendGas(G_SHA3.cost()); break; case SLOAD: - program.spendGas( GasLedger.G_SLOAD ); + program.spendGas(G_SLOAD.cost()); break; case SSTORE: // todo: calc gas in the execution // todo: according to the size break; case BALANCE: - program.spendGas( GasLedger.G_BALANCE ); + program.spendGas(G_BALANCE.cost()); break; case CREATE: - program.spendGas( GasLedger.G_CREATE ); + program.spendGas(G_CREATE.cost()); break; case CALL: - program.spendGas( GasLedger.G_CALL ); + program.spendGas(G_CALL.cost()); break; case MSTORE8: case MSTORE: @@ -58,7 +59,7 @@ public class VM { // todo: according to the size break; default: - program.spendGas( GasLedger.G_STEP ); + program.spendGas( G_STEP.cost() ); break; } @@ -472,11 +473,11 @@ public class VM { DataWord oldValue = program.storageLoad(addr); program.storageSave(addr, value); if (oldValue == null && !value.isZero()){ - program.spendGas(GasLedger.G_SSTORE * 2); + program.spendGas(G_SSTORE.cost() * 2); } else if (oldValue != null && value.isZero()){ - program.spendGas(GasLedger.G_SSTORE * 0); + program.spendGas(G_SSTORE.cost() * 0); } else - program.spendGas(GasLedger.G_SSTORE); + program.spendGas(G_SSTORE.cost()); program.step(); } @@ -554,7 +555,7 @@ public class VM { // memory gas calc int newMemSize = program.getMemSize(); - program.spendGas(GasLedger.G_MEMORY * (newMemSize - oldMemSize) /32); + program.spendGas(G_MEMORY.cost() * (newMemSize - oldMemSize) /32); } program.fullTrace(); } catch (RuntimeException e) { diff --git a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java index 773af8dc..f0914fd7 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java @@ -1,5 +1,7 @@ package org.ethereum.core; +import java.math.BigInteger; + import org.ethereum.net.message.BlocksMessage; import org.ethereum.net.message.StaticMessages; import org.ethereum.util.RLPList; @@ -89,7 +91,10 @@ public class BlockTest { @Test public void testCalcDifficulty() { - // Block.calcDifficulty() + Block genesis = Genesis.getInstance(); + byte[] diffBytes = genesis.calcDifficulty(); + BigInteger difficulty = new BigInteger(1, diffBytes); + System.out.println(difficulty.toString()); fail("Yet to be implemented."); } From dcd69f26ea925358d12067741b1b47a2538a4cc6 Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 16:19:32 +0200 Subject: [PATCH 04/13] Change my mind on using constants instead of enums for Gas --- .../src/main/java/org/ethereum/vm/Gas.java | 36 +++++++------------ .../src/main/java/org/ethereum/vm/VM.java | 21 ++++++----- 2 files changed, 23 insertions(+), 34 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java b/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java index 99bd5724..2bdb2afe 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java @@ -6,28 +6,18 @@ package org.ethereum.vm; * computation engine; its price is set by the Transaction and miners are free to * ignore Transactions whose Gas price is too low. */ -public enum Gas { +public class Gas { - G_STEP(1), - G_STOP(0), - G_SUICIDE(0), - G_SLOAD(20), - G_SHA3(20), - G_SSTORE(100), - G_BALANCE(20), - G_CREATE(100), - G_CALL(20), - G_MEMORY(1), - G_TXDATA(5), - G_TRANSACTION(500); - - private int cost; - - private Gas(int value) { - this.cost = value; - } - - public int cost() { - return cost; - } + public static int STEP = 1; + public static int STOP = 0; + public static int SUICIDE = 0; + public static int SLOAD = 20; + public static int SHA3 = 20; + public static int SSTORE = 100; + public static int BALANCE = 20; + public static int CREATE = 100; + public static int CALL = 20; + public static int MEMORY = 1; + public static int TXDATA = 5; + public static int TRANSACTION = 500; } \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java index 712c5321..ff68f3b0 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java @@ -8,7 +8,6 @@ import java.math.BigInteger; import java.nio.ByteBuffer; import static org.ethereum.vm.OpCode.PUSH1; -import static org.ethereum.vm.Gas.*; /** * www.ethereumJ.com @@ -35,23 +34,23 @@ public class VM { switch (OpCode.code(op)) { case SHA3: - program.spendGas(G_SHA3.cost()); + program.spendGas(Gas.SHA3); break; case SLOAD: - program.spendGas(G_SLOAD.cost()); + program.spendGas(Gas.SLOAD); break; case SSTORE: // todo: calc gas in the execution // todo: according to the size break; case BALANCE: - program.spendGas(G_BALANCE.cost()); + program.spendGas(Gas.BALANCE); break; case CREATE: - program.spendGas(G_CREATE.cost()); + program.spendGas(Gas.CREATE); break; case CALL: - program.spendGas(G_CALL.cost()); + program.spendGas(Gas.CALL); break; case MSTORE8: case MSTORE: @@ -59,7 +58,7 @@ public class VM { // todo: according to the size break; default: - program.spendGas( G_STEP.cost() ); + program.spendGas(Gas.STEP); break; } @@ -473,11 +472,11 @@ public class VM { DataWord oldValue = program.storageLoad(addr); program.storageSave(addr, value); if (oldValue == null && !value.isZero()){ - program.spendGas(G_SSTORE.cost() * 2); + program.spendGas(Gas.SSTORE * 2); } else if (oldValue != null && value.isZero()){ - program.spendGas(G_SSTORE.cost() * 0); + program.spendGas(Gas.SSTORE * 0); } else - program.spendGas(G_SSTORE.cost()); + program.spendGas(Gas.SSTORE); program.step(); } @@ -555,7 +554,7 @@ public class VM { // memory gas calc int newMemSize = program.getMemSize(); - program.spendGas(G_MEMORY.cost() * (newMemSize - oldMemSize) /32); + program.spendGas(Gas.MEMORY * (newMemSize - oldMemSize) /32); } program.fullTrace(); } catch (RuntimeException e) { From eb46749f5338da4ea8e276dfc300e03fd8acf9b0 Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 16:37:20 +0200 Subject: [PATCH 05/13] Settle on GasCost for classname --- .../ethereum/vm/{Gas.java => GasCost.java} | 2 +- .../src/main/java/org/ethereum/vm/VM.java | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) rename ethereumj-core/src/main/java/org/ethereum/vm/{Gas.java => GasCost.java} (96%) diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java b/ethereumj-core/src/main/java/org/ethereum/vm/GasCost.java similarity index 96% rename from ethereumj-core/src/main/java/org/ethereum/vm/Gas.java rename to ethereumj-core/src/main/java/org/ethereum/vm/GasCost.java index 2bdb2afe..ecc26842 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/GasCost.java @@ -6,7 +6,7 @@ package org.ethereum.vm; * computation engine; its price is set by the Transaction and miners are free to * ignore Transactions whose Gas price is too low. */ -public class Gas { +public class GasCost { public static int STEP = 1; public static int STOP = 0; diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java index ff68f3b0..d1f2297f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java @@ -34,23 +34,23 @@ public class VM { switch (OpCode.code(op)) { case SHA3: - program.spendGas(Gas.SHA3); + program.spendGas(GasCost.SHA3); break; case SLOAD: - program.spendGas(Gas.SLOAD); + program.spendGas(GasCost.SLOAD); break; case SSTORE: // todo: calc gas in the execution // todo: according to the size break; case BALANCE: - program.spendGas(Gas.BALANCE); + program.spendGas(GasCost.BALANCE); break; case CREATE: - program.spendGas(Gas.CREATE); + program.spendGas(GasCost.CREATE); break; case CALL: - program.spendGas(Gas.CALL); + program.spendGas(GasCost.CALL); break; case MSTORE8: case MSTORE: @@ -58,7 +58,7 @@ public class VM { // todo: according to the size break; default: - program.spendGas(Gas.STEP); + program.spendGas(GasCost.STEP); break; } @@ -472,11 +472,11 @@ public class VM { DataWord oldValue = program.storageLoad(addr); program.storageSave(addr, value); if (oldValue == null && !value.isZero()){ - program.spendGas(Gas.SSTORE * 2); + program.spendGas(GasCost.SSTORE * 2); } else if (oldValue != null && value.isZero()){ - program.spendGas(Gas.SSTORE * 0); + program.spendGas(GasCost.SSTORE * 0); } else - program.spendGas(Gas.SSTORE); + program.spendGas(GasCost.SSTORE); program.step(); } @@ -554,7 +554,7 @@ public class VM { // memory gas calc int newMemSize = program.getMemSize(); - program.spendGas(Gas.MEMORY * (newMemSize - oldMemSize) /32); + program.spendGas(GasCost.MEMORY * (newMemSize - oldMemSize) /32); } program.fullTrace(); } catch (RuntimeException e) { From f59e2408f94f01cf1fb9d6cf05e8d40c6304fc0c Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 17:27:38 +0200 Subject: [PATCH 06/13] Remove call to Blockchain DB from Genesis and fix default calc values --- .../main/java/org/ethereum/core/Block.java | 6 +++--- .../main/java/org/ethereum/core/Genesis.java | 21 +++++++++++++++++-- .../java/org/ethereum/core/BlockTest.java | 6 ++++-- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Block.java b/ethereumj-core/src/main/java/org/ethereum/core/Block.java index f6b452a0..fff0fe6a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Block.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Block.java @@ -226,7 +226,7 @@ public class Block { toStringBuff.setLength(0); toStringBuff.append("BlockData ["); - toStringBuff.append(" hash=" + ByteUtil.toHexString(hash)).append(""); + toStringBuff.append(" hash=" + ByteUtil.toHexString(this.getHash())).append(""); toStringBuff.append(header.toFlatString()); for (Transaction tx : getTransactionsList()){ @@ -313,8 +313,8 @@ public class Block { * @return */ public long calcGasLimit() { - if (this.header.getParentHash() == null) - return 1000000L; + if (Arrays.equals(this.header.getParentHash(), Genesis.PARENT_HASH)) + return Genesis.GAS_LIMIT; else { Block parent = this.getParent(); return Math.max(MIN_GAS_LIMIT, (parent.header.getGasLimit() * (1024 - 1) + (parent.header.getGasUsed() * 6 / 5)) / 1024); diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java b/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java index 5058384e..e54e39fc 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java @@ -9,10 +9,29 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; +/** + * The genesis block is the first block in the chain and has fixed values according to + * the protocol specification. The genesis block is 13 items, and is specified thus: + * + * ( zerohash_256 , SHA3 RLP () , zerohash_160 , stateRoot, 0, 2^22 , 0, 0, 1000000, 0, 0, 0, SHA3 (42) , (), () ) + * + * - Where zerohash_256 refers to the parent hash, a 256-bit hash which is all zeroes; + * - zerohash_160 refers to the coinbase address, a 160-bit hash which is all zeroes; + * - 2^22 refers to the difficulty; + * - 0 refers to the timestamp (the Unix epoch); + * - the transaction trie root and extradata are both 0, being equivalent to the empty byte array. + * - The sequences of both uncles and transactions are empty and represented by (). + * - SHA3 (42) refers to the SHA3 hash of a byte array of length one whose first and only byte is of value 42. + * - SHA3 RLP () value refers to the hash of the uncle lists in RLP, both empty lists. + * + * See Yellow Paper: http://www.gavwood.com/Paper.pdf (Appendix I. Genesis Block) + */ public class Genesis extends Block { Logger logger = LoggerFactory.getLogger(this.getClass()); + // The proof-of-concept series include a development premine, making the state root hash + // some value stateRoot. The latest documentation should be consulted for the value of the state root. private AccountState acct = new AccountState(BigInteger.ZERO, BigInteger.valueOf(2).pow(200)); private String[] premine = new String[] { "2ef47100e0787b915105fd5e3f4ff6752079d5cb", // # (M) @@ -53,8 +72,6 @@ public class Genesis extends Block { } logger.info("Genesis-hash: " + Hex.toHexString(this.getHash())); logger.info("Genesis-stateRoot: " + Hex.toHexString(this.getStateRoot())); - - Config.CHAIN_DB.put(getParentHash(), getEncoded()); } public static Block getInstance() { diff --git a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java index f0914fd7..a6edcbc3 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java @@ -94,13 +94,15 @@ public class BlockTest { Block genesis = Genesis.getInstance(); byte[] diffBytes = genesis.calcDifficulty(); BigInteger difficulty = new BigInteger(1, diffBytes); - System.out.println(difficulty.toString()); + System.out.println("Genesis difficulty = " + difficulty.toString()); fail("Yet to be implemented."); } @Test public void testCalcGasLimit() { - // Block.calcGasLimit() + Block genesis = Genesis.getInstance(); + long gasLimit = genesis.calcGasLimit(); + System.out.println("Genesis gasLimit = " + gasLimit); fail("Yet to be implemented."); } } \ No newline at end of file From 693930c7e4d174cb191edc223e016aaa6480a29d Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 15:49:34 +0200 Subject: [PATCH 07/13] Add failing Block calc tests and update Denomination enum --- .../main/java/org/ethereum/core/Block.java | 31 +++++++------- .../java/org/ethereum/core/Blockchain.java | 36 ++++++++-------- .../java/org/ethereum/core/Denomination.java | 15 ++++--- .../main/java/org/ethereum/core/Genesis.java | 21 +++++++++- .../java/org/ethereum/core/Transaction.java | 2 +- .../main/java/org/ethereum/vm/GasCost.java | 23 +++++++++++ .../main/java/org/ethereum/vm/GasLedger.java | 41 ------------------- .../src/main/java/org/ethereum/vm/VM.java | 20 ++++----- .../java/org/ethereum/core/BlockTest.java | 19 +++++++++ 9 files changed, 116 insertions(+), 92 deletions(-) create mode 100644 ethereumj-core/src/main/java/org/ethereum/vm/GasCost.java delete mode 100644 ethereumj-core/src/main/java/org/ethereum/vm/GasLedger.java diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Block.java b/ethereumj-core/src/main/java/org/ethereum/core/Block.java index bda7e510..80b87bd1 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Block.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Block.java @@ -22,7 +22,7 @@ import java.util.List; */ public class Block { - /* A scalar longValue equal to the mininum limit of gas expenditure per block */ + /* A scalar value equal to the mininum limit of gas expenditure per block */ private static long MIN_GAS_LIMIT = BigInteger.valueOf(10).pow(4).longValue(); private BlockHeader header; @@ -38,7 +38,6 @@ public class Block { private byte[] rlpEncoded; private boolean parsed = false; - private byte[] hash; private Trie txsState; @@ -64,9 +63,6 @@ public class Block { this.parsed = true; } - // [parent_hash, uncles_hash, coinbase, state_root, tx_trie_root, - // difficulty, number, minGasPrice, gasLimit, gasUsed, timestamp, - // extradata, nonce] private void parseRLP() { RLPList params = (RLPList) RLP.decode2(rlpEncoded); @@ -87,7 +83,6 @@ public class Block { this.uncleList.add(blockData); } this.parsed = true; - this.hash = this.getHash(); } public byte[] getHash(){ @@ -144,6 +139,10 @@ public class Block { if (!parsed) parseRLP(); return this.header.getMinGasPrice(); } + + public boolean isGenesis() { + return this.header.getNumber() == 0; + } public long getGasLimit() { if (!parsed) parseRLP(); @@ -204,7 +203,7 @@ public class Block { toStringBuff.setLength(0); toStringBuff.append("BlockData [\n"); - toStringBuff.append(" hash=" + ByteUtil.toHexString(hash)).append("\n"); + toStringBuff.append(" hash=" + ByteUtil.toHexString(this.getHash())).append("\n"); toStringBuff.append(header.toString()); for (TransactionReceipt txReceipt : getTxReceiptList()) { @@ -221,7 +220,7 @@ public class Block { toStringBuff.setLength(0); toStringBuff.append("BlockData ["); - toStringBuff.append(" hash=" + ByteUtil.toHexString(hash)).append(""); + toStringBuff.append(" hash=" + ByteUtil.toHexString(this.getHash())).append(""); toStringBuff.append(header.toFlatString()); for (Transaction tx : getTransactionsList()){ @@ -289,15 +288,15 @@ public class Block { * likely next period. Conversely, if the period is too large, the difficulty, * and expected time to the next block, is reduced. */ - private boolean isValid() { - boolean isValid = false; + public boolean isValid() { + boolean isValid = true; // verify difficulty meets requirements - isValid = this.getDifficulty() == this.calcDifficulty(); + //isValid = this.getDifficulty() == this.calcDifficulty(); // verify gasLimit meets requirements - isValid = this.getGasLimit() == this.calcGasLimit(); + //isValid = this.getGasLimit() == this.calcGasLimit(); // verify timestamp meets requirements - isValid = this.getTimestamp() > this.getParent().getTimestamp(); + //isValid = this.getTimestamp() > this.getParent().getTimestamp(); return isValid; } @@ -309,8 +308,8 @@ public class Block { * @return */ public long calcGasLimit() { - if (this.header.getParentHash() == null) - return 1000000L; + if (this.isGenesis()) + return Genesis.GAS_LIMIT; else { Block parent = this.getParent(); return Math.max(MIN_GAS_LIMIT, (parent.header.getGasLimit() * (1024 - 1) + (parent.header.getGasUsed() * 6 / 5)) / 1024); @@ -318,7 +317,7 @@ public class Block { } public byte[] calcDifficulty() { - if (this.header.getParentHash() == null) + if (this.isGenesis()) return Genesis.DIFFICULTY; else { Block parent = this.getParent(); diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java b/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java index 06164e0b..23371b64 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java @@ -6,22 +6,27 @@ import org.ethereum.net.message.StaticMessages; import org.ethereum.net.submit.WalletTransaction; import org.iq80.leveldb.DBIterator; import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; import java.io.IOException; import java.util.*; +import javax.inject.Inject; + import static org.ethereum.core.Denomination.*; public class Blockchain extends ArrayList { private static final long serialVersionUID = -143590724563460486L; - private static Logger logger = LoggerFactory.getLogger(Blockchain.class); + private static long INITIAL_MIN_GAS_PRICE = 10 * SZABO.longValue(); // to avoid using minGasPrice=0 from Genesis + + @Inject + private Logger logger; private Database db; private Wallet wallet; + private long gasPrice = 1000; private Block lastBlock; @@ -83,27 +88,24 @@ public class Blockchain extends ArrayList { } private void addBlock(Block block) { - this.wallet.processBlock(block); - - // that is the genesis case , we don't want to rely - // on this price will use default 10000000000000 - // todo: refactor this longValue some constant defaults class 10000000000000L - this.gasPrice = (block.getMinGasPrice() == 0) ? 10 * SZABO.longValue() : block.getMinGasPrice(); - - if(lastBlock == null || block.getNumber() > lastBlock.getNumber()) - this.lastBlock = block; - this.add(block); + if(block.isValid()) { + this.wallet.processBlock(block); + + // that is the genesis case , we don't want to rely + // on this price will use default 10000000000000 + // todo: refactor this longValue some constant defaults class 10000000000000L + this.gasPrice = block.isGenesis() ? INITIAL_MIN_GAS_PRICE : block.getMinGasPrice(); + + if(lastBlock == null || block.getNumber() > lastBlock.getNumber()) + this.lastBlock = block; + this.add(block); + } } public long getGasPrice() { return gasPrice; } - - - - - /*********************************************************************** * 1) the dialog put a pending transaction on the list * 2) the dialog send the transaction to a net diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Denomination.java b/ethereumj-core/src/main/java/org/ethereum/core/Denomination.java index edfbc6f7..9a4af508 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Denomination.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Denomination.java @@ -10,18 +10,23 @@ public enum Denomination { SHANNON(newBigInt(9)), SZABO(newBigInt(12)), FINNY(newBigInt(15)), - ETHER(newBigInt(18)); - + ETHER(newBigInt(18)), + EINSTEIN(newBigInt(21)), + DOUGLAS(newBigInt(42)); + private BigInteger amount; - + private Denomination(BigInteger value) { this.amount = value; } - public BigInteger getDenomination() { + public BigInteger value() { return amount; } - public long longValue() {return getDenomination().longValue();} + + public long longValue() { + return value().longValue(); + } private static BigInteger newBigInt(int value) { return BigInteger.valueOf(10).pow(value); diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java b/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java index 2dc391c5..3b23166a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java @@ -9,10 +9,29 @@ import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; +/** + * The genesis block is the first block in the chain and has fixed values according to + * the protocol specification. The genesis block is 13 items, and is specified thus: + * + * ( zerohash_256 , SHA3 RLP () , zerohash_160 , stateRoot, 0, 2^22 , 0, 0, 1000000, 0, 0, 0, SHA3 (42) , (), () ) + * + * - Where zerohash_256 refers to the parent hash, a 256-bit hash which is all zeroes; + * - zerohash_160 refers to the coinbase address, a 160-bit hash which is all zeroes; + * - 2^22 refers to the difficulty; + * - 0 refers to the timestamp (the Unix epoch); + * - the transaction trie root and extradata are both 0, being equivalent to the empty byte array. + * - The sequences of both uncles and transactions are empty and represented by (). + * - SHA3 (42) refers to the SHA3 hash of a byte array of length one whose first and only byte is of value 42. + * - SHA3 RLP () value refers to the hash of the uncle lists in RLP, both empty lists. + * + * See Yellow Paper: http://www.gavwood.com/Paper.pdf (Appendix I. Genesis Block) + */ public class Genesis extends Block { Logger logger = LoggerFactory.getLogger(this.getClass()); + // The proof-of-concept series include a development premine, making the state root hash + // some value stateRoot. The latest documentation should be consulted for the value of the state root. private AccountState acct = new AccountState(BigInteger.ZERO, BigInteger.valueOf(2).pow(200)); private String[] premine = new String[] { "2ef47100e0787b915105fd5e3f4ff6752079d5cb", // # (M) @@ -53,8 +72,6 @@ public class Genesis extends Block { } logger.info("Genesis-hash: " + Hex.toHexString(this.getHash())); logger.info("Genesis-stateRoot: " + Hex.toHexString(this.getStateRoot())); - - WorldManager.instance.chainDB.put(getParentHash(), getEncoded()); } public static Block getInstance() { diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Transaction.java b/ethereumj-core/src/main/java/org/ethereum/core/Transaction.java index 40a57d37..6519264c 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Transaction.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Transaction.java @@ -17,7 +17,7 @@ import java.security.SignatureException; import java.util.Arrays; /** - * A transaction (formally, T ) is a single cryptographically + * A transaction (formally, T) is a single cryptographically * signed instruction sent by an actor external to Ethereum. * An external actor can be a person (via a mobile device or desktop computer) * or could be from a piece of automated software running on a server. diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/GasCost.java b/ethereumj-core/src/main/java/org/ethereum/vm/GasCost.java new file mode 100644 index 00000000..ecc26842 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/vm/GasCost.java @@ -0,0 +1,23 @@ +package org.ethereum.vm; + +/** + * The fundamental network cost unit. Paid for exclusively by Ether, which is converted + * freely to and from Gas as required. Gas does not exist outside of the internal Ethereum + * computation engine; its price is set by the Transaction and miners are free to + * ignore Transactions whose Gas price is too low. + */ +public class GasCost { + + public static int STEP = 1; + public static int STOP = 0; + public static int SUICIDE = 0; + public static int SLOAD = 20; + public static int SHA3 = 20; + public static int SSTORE = 100; + public static int BALANCE = 20; + public static int CREATE = 100; + public static int CALL = 20; + public static int MEMORY = 1; + public static int TXDATA = 5; + public static int TRANSACTION = 500; +} \ No newline at end of file diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/GasLedger.java b/ethereumj-core/src/main/java/org/ethereum/vm/GasLedger.java deleted file mode 100644 index 314cdcbf..00000000 --- a/ethereumj-core/src/main/java/org/ethereum/vm/GasLedger.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.ethereum.vm; - -import java.util.HashMap; - -/** - * www.ethereumJ.com - * User: Roman Mandeleil - * Created on: 04/06/2014 23:58 - */ - -public class GasLedger { - -/* YP Appendix B. - Gstep 1 Default amount of gas to pay for execution cycle. - Gstop 0 Nothing paid for the STOP operation. - Gsuicide 0 Nothing paid for the SUICIDE operation. - Gsha3 20 Paid for a SHA3 operation. - Gsload 20 Paid for a SLOAD operation. - Gsstore 100 Paid for a normal SSTORE operation (doubled or waived sometimes). - Gbalance 20 Paid for a BALANCE operation. - Gcreate 100 Paid for a CREATE operation. - Gcall 20 Paid for a CALL operation. - Gmemory 1 Paid for every additional word when expanding memory. - Gtxdata 5 Paid for every byte of data or code for a transaction. - Gtransaction 500 Paid for every transaction. - */ - - - public static int G_STEP = 1; - public static int G_STOP = 0; - public static int G_SUICIDE = 0; - public static int G_SLOAD = 20; - public static int G_SHA3 = 20; - public static int G_SSTORE = 100; - public static int G_BALANCE = 20; - public static int G_CREATE = 100; - public static int G_CALL = 20; - public static int G_MEMORY = 1; - public static int G_TXDATA = 5; - public static int G_TRANSACTION = 500; -} diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java index af5c2d5c..b95177db 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java @@ -34,23 +34,23 @@ public class VM { switch (OpCode.code(op)) { case SHA3: - program.spendGas( GasLedger.G_SHA3 ); + program.spendGas(GasCost.SHA3); break; case SLOAD: - program.spendGas( GasLedger.G_SLOAD ); + program.spendGas(GasCost.SLOAD); break; case SSTORE: // todo: calc gas in the execution // todo: according to the size break; case BALANCE: - program.spendGas( GasLedger.G_BALANCE ); + program.spendGas(GasCost.BALANCE); break; case CREATE: - program.spendGas( GasLedger.G_CREATE ); + program.spendGas(GasCost.CREATE); break; case CALL: - program.spendGas( GasLedger.G_CALL ); + program.spendGas(GasCost.CALL); break; case MSTORE8: case MSTORE: @@ -58,7 +58,7 @@ public class VM { // todo: according to the size break; default: - program.spendGas( GasLedger.G_STEP ); + program.spendGas(GasCost.STEP); break; } @@ -472,11 +472,11 @@ public class VM { DataWord oldValue = program.storageLoad(addr); program.storageSave(addr, value); if (oldValue == null && !value.isZero()){ - program.spendGas(GasLedger.G_SSTORE * 2); + program.spendGas(GasCost.SSTORE * 2); } else if (oldValue != null && value.isZero()){ - program.spendGas(GasLedger.G_SSTORE * 0); + program.spendGas(GasCost.SSTORE * 0); } else - program.spendGas(GasLedger.G_SSTORE); + program.spendGas(GasCost.SSTORE); program.step(); } @@ -573,7 +573,7 @@ public class VM { // memory gas calc int newMemSize = program.getMemSize(); - program.spendGas(GasLedger.G_MEMORY * (newMemSize - oldMemSize) /32); + program.spendGas(GasCost.MEMORY * (newMemSize - oldMemSize) /32); } program.fullTrace(); } catch (RuntimeException e) { diff --git a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java index 2210d050..21158254 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java @@ -1,5 +1,7 @@ package org.ethereum.core; +import java.math.BigInteger; + import org.ethereum.net.message.BlocksMessage; import org.ethereum.net.message.StaticMessages; import org.ethereum.util.RLPList; @@ -86,4 +88,21 @@ public class BlockTest { BlocksMessage blockData = new BlocksMessage(rlpList); System.out.println(blockData.toString()); } + + @Test + public void testCalcDifficulty() { + Block genesis = Genesis.getInstance(); + byte[] diffBytes = genesis.calcDifficulty(); + BigInteger difficulty = new BigInteger(1, diffBytes); + System.out.println("Genesis difficulty = " + difficulty.toString()); + fail("Yet to be implemented."); + } + + @Test + public void testCalcGasLimit() { + Block genesis = Genesis.getInstance(); + long gasLimit = genesis.calcGasLimit(); + System.out.println("Genesis gasLimit = " + gasLimit); + fail("Yet to be implemented."); + } } \ No newline at end of file From 6407f48c3af9d74f533dfaf657e5f6ca2243a6a3 Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 15:49:34 +0200 Subject: [PATCH 08/13] Add failing Block calc tests and update Denomination enum --- .../src/main/java/org/ethereum/core/Blockchain.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java b/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java index 23371b64..be2ee87c 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java @@ -90,13 +90,11 @@ public class Blockchain extends ArrayList { private void addBlock(Block block) { if(block.isValid()) { this.wallet.processBlock(block); - // that is the genesis case , we don't want to rely // on this price will use default 10000000000000 // todo: refactor this longValue some constant defaults class 10000000000000L this.gasPrice = block.isGenesis() ? INITIAL_MIN_GAS_PRICE : block.getMinGasPrice(); - - if(lastBlock == null || block.getNumber() > lastBlock.getNumber()) + if(lastBlock == null || block.getNumber() > lastBlock.getNumber()) this.lastBlock = block; this.add(block); } From 7013e1ab1a01237141565163a674695a4230d72e Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 16:13:05 +0200 Subject: [PATCH 09/13] Replace GasLedger with Gas enum class --- .../main/java/org/ethereum/core/Block.java | 2 ++ .../src/main/java/org/ethereum/vm/Gas.java | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 ethereumj-core/src/main/java/org/ethereum/vm/Gas.java diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Block.java b/ethereumj-core/src/main/java/org/ethereum/core/Block.java index 80b87bd1..26d422a4 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Block.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Block.java @@ -9,6 +9,8 @@ import org.ethereum.util.RLPElement; import org.ethereum.util.RLPList; import org.spongycastle.util.BigIntegers; +import edu.emory.mathcs.backport.java.util.Arrays; + import java.math.BigInteger; import java.util.ArrayList; import java.util.List; diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java b/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java new file mode 100644 index 00000000..99bd5724 --- /dev/null +++ b/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java @@ -0,0 +1,33 @@ +package org.ethereum.vm; + +/** + * The fundamental network cost unit. Paid for exclusively by Ether, which is converted + * freely to and from Gas as required. Gas does not exist outside of the internal Ethereum + * computation engine; its price is set by the Transaction and miners are free to + * ignore Transactions whose Gas price is too low. + */ +public enum Gas { + + G_STEP(1), + G_STOP(0), + G_SUICIDE(0), + G_SLOAD(20), + G_SHA3(20), + G_SSTORE(100), + G_BALANCE(20), + G_CREATE(100), + G_CALL(20), + G_MEMORY(1), + G_TXDATA(5), + G_TRANSACTION(500); + + private int cost; + + private Gas(int value) { + this.cost = value; + } + + public int cost() { + return cost; + } +} \ No newline at end of file From 5d4814a8eb90b56298d0f91cb4ee37a2198c249d Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 16:19:32 +0200 Subject: [PATCH 10/13] Change my mind on using constants instead of enums for Gas --- .../src/main/java/org/ethereum/vm/Gas.java | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 ethereumj-core/src/main/java/org/ethereum/vm/Gas.java diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java b/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java deleted file mode 100644 index 99bd5724..00000000 --- a/ethereumj-core/src/main/java/org/ethereum/vm/Gas.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.ethereum.vm; - -/** - * The fundamental network cost unit. Paid for exclusively by Ether, which is converted - * freely to and from Gas as required. Gas does not exist outside of the internal Ethereum - * computation engine; its price is set by the Transaction and miners are free to - * ignore Transactions whose Gas price is too low. - */ -public enum Gas { - - G_STEP(1), - G_STOP(0), - G_SUICIDE(0), - G_SLOAD(20), - G_SHA3(20), - G_SSTORE(100), - G_BALANCE(20), - G_CREATE(100), - G_CALL(20), - G_MEMORY(1), - G_TXDATA(5), - G_TRANSACTION(500); - - private int cost; - - private Gas(int value) { - this.cost = value; - } - - public int cost() { - return cost; - } -} \ No newline at end of file From 9880f3ec156cd5a3a3a172bb1b956099f49565d5 Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 17:27:38 +0200 Subject: [PATCH 11/13] Remove call to Blockchain DB from Genesis and fix default calc values --- ethereumj-core/src/main/java/org/ethereum/core/Genesis.java | 1 - .../src/test/java/org/ethereum/core/BlockTest.java | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java b/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java index 3b23166a..9eee6468 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java @@ -1,7 +1,6 @@ package org.ethereum.core; import org.ethereum.crypto.HashUtil; -import org.ethereum.manager.WorldManager; import org.ethereum.util.RLP; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java index 21158254..2c7a3550 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java @@ -91,9 +91,15 @@ public class BlockTest { @Test public void testCalcDifficulty() { +<<<<<<< HEAD Block genesis = Genesis.getInstance(); byte[] diffBytes = genesis.calcDifficulty(); BigInteger difficulty = new BigInteger(1, diffBytes); +======= + Block genesis = Genesis.getInstance(); + byte[] diffBytes = genesis.calcDifficulty(); + BigInteger difficulty = new BigInteger(1, diffBytes); +>>>>>>> Remove call to Blockchain DB from Genesis and fix default calc values System.out.println("Genesis difficulty = " + difficulty.toString()); fail("Yet to be implemented."); } From 0dab8330f1a0102b482ae5fd419fd4d5bee8b8f2 Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 17:49:02 +0200 Subject: [PATCH 12/13] Add comment to Block calculation --- .../src/main/java/org/ethereum/core/Block.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Block.java b/ethereumj-core/src/main/java/org/ethereum/core/Block.java index 26d422a4..bde2061f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Block.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Block.java @@ -9,8 +9,6 @@ import org.ethereum.util.RLPElement; import org.ethereum.util.RLPList; import org.spongycastle.util.BigIntegers; -import edu.emory.mathcs.backport.java.util.Arrays; - import java.math.BigInteger; import java.util.ArrayList; import java.util.List; @@ -305,9 +303,8 @@ public class Block { /** * Calculate GasLimit - * max(10000, (parent gas limit * (1024 - 1) + (parent gas used * 6 / 5)) / 1024) - * - * @return + * See Yellow Paper: http://www.gavwood.com/Paper.pdf - page 5, 4.3.4 (25) + * @return long value of the gasLimit */ public long calcGasLimit() { if (this.isGenesis()) @@ -318,6 +315,11 @@ public class Block { } } + /** + * Calculate Difficulty + * See Yellow Paper: http://www.gavwood.com/Paper.pdf - page 5, 4.3.4 (24) + * @return byte array value of the difficulty + */ public byte[] calcDifficulty() { if (this.isGenesis()) return Genesis.DIFFICULTY; From a00ff1e205b3f9671f9eb93052c7112025c3d76f Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 18:47:14 +0200 Subject: [PATCH 13/13] Mega merge with major refactoring --- .../main/java/org/ethereum/core/Blockchain.java | 14 +++++--------- .../src/main/java/org/ethereum/core/Genesis.java | 4 ++-- .../src/test/java/org/ethereum/core/BlockTest.java | 6 ------ 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java b/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java index be2ee87c..2fea272c 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java @@ -6,38 +6,34 @@ import org.ethereum.net.message.StaticMessages; import org.ethereum.net.submit.WalletTransaction; import org.iq80.leveldb.DBIterator; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; import java.io.IOException; import java.util.*; -import javax.inject.Inject; - import static org.ethereum.core.Denomination.*; public class Blockchain extends ArrayList { private static final long serialVersionUID = -143590724563460486L; - private static long INITIAL_MIN_GAS_PRICE = 10 * SZABO.longValue(); // to avoid using minGasPrice=0 from Genesis - - @Inject - private Logger logger; + private static Logger logger = LoggerFactory.getLogger(Blockchain.class); + // to avoid using minGasPrice=0 from Genesis for the wallet + private static long INITIAL_MIN_GAS_PRICE = 10 * SZABO.longValue(); + private Database db; private Wallet wallet; private long gasPrice = 1000; private Block lastBlock; - // This map of transaction designed // to approve the tx by external trusted peer private Map walletTransactions = Collections.synchronizedMap(new HashMap()); - - public Blockchain(Wallet wallet) { this.db = WorldManager.instance.chainDB; this.wallet = wallet; diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java b/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java index 9eee6468..9db273e7 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Genesis.java @@ -1,13 +1,13 @@ package org.ethereum.core; +import java.math.BigInteger; + import org.ethereum.crypto.HashUtil; import org.ethereum.util.RLP; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; -import java.math.BigInteger; - /** * The genesis block is the first block in the chain and has fixed values according to * the protocol specification. The genesis block is 13 items, and is specified thus: diff --git a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java index 2c7a3550..21158254 100644 --- a/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/core/BlockTest.java @@ -91,15 +91,9 @@ public class BlockTest { @Test public void testCalcDifficulty() { -<<<<<<< HEAD Block genesis = Genesis.getInstance(); byte[] diffBytes = genesis.calcDifficulty(); BigInteger difficulty = new BigInteger(1, diffBytes); -======= - Block genesis = Genesis.getInstance(); - byte[] diffBytes = genesis.calcDifficulty(); - BigInteger difficulty = new BigInteger(1, diffBytes); ->>>>>>> Remove call to Blockchain DB from Genesis and fix default calc values System.out.println("Genesis difficulty = " + difficulty.toString()); fail("Yet to be implemented."); }