Strip trailing whitespace

This commit is contained in:
Chris Beams 2014-12-26 09:36:37 +01:00
parent 0827fb5c8f
commit e5fcf5b48e
No known key found for this signature in database
GPG Key ID: 3D214F8F5BC5ED73
142 changed files with 1301 additions and 1301 deletions

View File

@ -1,7 +1,7 @@
[![ScreenShot](http://i.imgur.com/lJw1Tui.jpg)]
# Welcome to ethereumj
# Welcome to ethereumj
[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/ethereum/ethereumj?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/ethereum/ethereumj.svg?branch=master)](https://travis-ci.org/ethereum/ethereumj) [![Coverage Status](https://coveralls.io/repos/ethereum/ethereumj/badge.png?branch=master)](https://coveralls.io/r/ethereum/ethereumj?branch=master)
[![Stories in Progress](https://badge.waffle.io/ethereum/ethereumj.png?title=In%20Progress&label=in_progress)](https://waffle.io/ethereum/ethereumj)
@ -10,18 +10,18 @@
The ethereumj library is a Java implementation of the Ethereum protocol.
This repository currently contains:
This repository currently contains:
* [core](ethereumj-core): the core library which can be included into your own Java project.
* [studio](ethereumj-studio): a simple graphic interface for Ethereum functionality and set of showcases for core usage.
* [studio](ethereumj-studio): a simple graphic interface for Ethereum functionality and set of showcases for core usage.
For an early peek, have a looki at this [video](https://youtu.be/D5ok7jh7AOg)
# Todo
The Ethereum protocol is currenty heavily in development, thus so is this implementation.
You can find a todo-list right [here](TODO.md) and the [milestone schedule](https://github.com/ethereum/ethereumj/milestones).
You can find a todo-list right [here](TODO.md) and the [milestone schedule](https://github.com/ethereum/ethereumj/milestones).
For questions you can reach us in #ethereumj on Freenode.
# Documentation
To start you can visit [Ethereum.org](https://www.ethereum.org) and if you are looking for more information on the concept, the [ethereum white paper](https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-White-Paper) is a good place to start as it outlines the vision. For the more technical minded, a protocol description can be found in the [yellow paper](http://gavwood.com/Paper.pdf) by Gavin Wood.
@ -34,6 +34,6 @@ https://bintray.com/ethereum/maven/org.ethereum/view
For building ethereumj-core or ethereumj-studio look in their own individual README
# License
# License
This software is released under the MIT license, read it [here](LICENSE)

28
TODO.md
View File

@ -4,26 +4,26 @@
----------------
- [ ] **GUI screen** a screen that will hold table with full state representation
- [ ] **SerpentCompiler** compile create(gas, mem_start, import("examples/mul2.se"))
- [ ] **SerpentCompiler** compile create(gas, mem_start, import("examples/mul2.se"))
https://github.com/ethereum/wiki/wiki/Serpent
- [ ] **SerpentCompiler** compile return(array) correct
- [ ] **ProgramPlayDialog** support internal calls
- [ ] **Performance:** BigInteger math change for constant arrays implementation
- [ ] **Performance:** BigInteger math change for constant arrays implementation
economy for memory allocation
- [ ] **Command Line:** add the headless run option
- [ ] **SerpentCompiler** Serpent new syntax:
(@> @< @/ @%) - unsigned operations
> < / % - default are all signed operations
+= -= *= /= %= @/= @%= - short form operations
- [ ] **Command Line:** add the headless run option
- [ ] **SerpentCompiler** Serpent new syntax:
(@> @< @/ @%) - unsigned operations
> < / % - default are all signed operations
+= -= *= /= %= @/= @%= - short form operations
share - code section
- [ ] **LLL_to_ASM compiler** list style language to EVM assembly compiler:
- [ ] **LLL_to_ASM compiler** list style language to EVM assembly compiler:
- [ ] **Use home-directory** Create .ethereumj in home-directory for blockchain, state & details database. Make configurable in system.properties so developer can choose user.dir without the creation of .ethereumj directory.
##### UnitTest:
##### UnitTest:
----------------
- [ ] **VM complex:** CREATE testing
- [ ] **VM complex:** CREATE testing
- [ ] **VM complex:** SUICIDE testing
- [ ] **SerpentCompiler** compile return(array) correct
- [ ] **WorldManager** apply transactions
@ -36,14 +36,14 @@ share - code section
- [X] ** Block Queue ** separate net layer and block processing layer, net layer should continue get
blocks in time the vm layer process them (not stuck for it)
- [X] **Build:** extract core module and studio application
- [x] **VM execution:** support CALL op
- [x] **VM execution:** support CALL op with in/out data
- [x] **VM execution:** support CALL op
- [x] **VM execution:** support CALL op with in/out data
- [x] **VM execution:** support CREATE op
- [x] **SerpentCompiler** compile create(gas, mem_start, mem_size)
- [x] **VM complex:** CALL testing for in arrays
- [x] **VM complex:** CALL testing for out result
- [x] **State management** trie for storage hash calculation
- [x] **State management** trie for storage hash calculation
and update hash into AccountState
- [x] **VM execution:** SUICIDE op adjust
- [x] **Testing by JSON files:** follow cpp client performs test case by getting json file contains the test describe

View File

@ -1,7 +1,7 @@
The core library API for Ethereum project can be included
into any other Java/Scala project by simple maven
script include:
into any other Java/Scala project by simple maven
script include:
```
<dependency>
@ -13,20 +13,20 @@ script include:
```
EthereumJ release repository can be found here:
EthereumJ release repository can be found here:
* https://bintray.com/ethereum/maven/org.ethereum/view
The showcase for ethereumj-core usage can be found in [ethereumj-studio](../ethereumj-studio)
###### :small_blue_diamond: Build instructions (maven)
1. build_1: [no test run] , [released to local repository] : ~> ` mvn clean install -Dmaven.test.skip=true `
2. build_2: [include test run] , [released to local repository] : ~> ` mvn clean install `
1. build_1: [no test run] , [released to local repository] : ~> ` mvn clean install -Dmaven.test.skip=true `
2. build_2: [include test run] , [released to local repository] : ~> ` mvn clean install `
###### :small_blue_diamond: release instructions (ant) (!) credential required
1. ` mvn install ` - which release the lib to a local repositroy
2. after the release - ` ant -f bintray-publish-version.xml `

View File

@ -446,5 +446,5 @@
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -13,7 +13,7 @@ import org.springframework.stereotype.Component;
/**
* Utility class to retrieve property values from the system.properties files
*
* @author Roman Mandeleil
* @author Roman Mandeleil
* Created on: 22/05/2014 19:22
*/
public class SystemProperties {
@ -46,7 +46,7 @@ public class SystemProperties {
private static Boolean DEFAULT_VM_TRACE = false;
private static String DEFAULT_VM_TRACE_DIR = "dmp";
private static int DEFAULT_PEER_LISTEN_PORT = 30303;
/* Testing */
private static Boolean DEFAULT_VMTEST_LOAD_LOCAL = false;
@ -281,17 +281,17 @@ public class SystemProperties {
logger.info("Key: " + key + ", Value: " + value);
}
}
/*
*
*
* Testing
*
*
*/
public boolean vmTestLoadLocal() {
if (prop.isEmpty() || !prop.containsKey("GitHubTests.VMTest.loadLocal")) return DEFAULT_VMTEST_LOAD_LOCAL;
return Boolean.parseBoolean(prop.getProperty("GitHubTests.VMTest.loadLocal"));
}
public static void main(String args[]) {
SystemProperties systemProperties = new SystemProperties();
systemProperties.print();

View File

@ -12,32 +12,32 @@ import static org.ethereum.crypto.HashUtil.EMPTY_TRIE_HASH;
public class AccountState {
private byte[] rlpEncoded;
/* A value equal to the number of transactions sent
* from this address, or, in the case of contract accounts,
* from this address, or, in the case of contract accounts,
* the number of contract-creations made by this account */
private BigInteger nonce;
/* A scalar value equal to the number of Wei owned by this address */
private BigInteger balance;
/* A 256-bit hash of the root node of a trie structure
* that encodes the storage contents of the contract,
* itself a simple mapping between byte arrays of size 32.
* The hash is formally denoted σ[a] s .
*
* Since I typically wish to refer not to the tries root hash
/* A 256-bit hash of the root node of a trie structure
* that encodes the storage contents of the contract,
* itself a simple mapping between byte arrays of size 32.
* The hash is formally denoted σ[a] s .
*
* Since I typically wish to refer not to the tries root hash
* but to the underlying set of key/value pairs stored within,
* I define a convenient equivalence TRIE (σ[a] s ) σ[a] s .
* It shall be understood that σ[a] s is not a physical member
* I define a convenient equivalence TRIE (σ[a] s ) σ[a] s .
* It shall be understood that σ[a] s is not a physical member
* of the account and does not contribute to its later serialisation */
private byte[] stateRoot = EMPTY_TRIE_HASH;
/* The hash of the EVM code of this contractthis is the code
* that gets executed should this address receive a message call;
* it is immutable and thus, unlike all other fields, cannot be changed
* after construction. All such code fragments are contained in
* the state database under their corresponding hashes for later
/* The hash of the EVM code of this contractthis is the code
* that gets executed should this address receive a message call;
* it is immutable and thus, unlike all other fields, cannot be changed
* after construction. All such code fragments are contained in
* the state database under their corresponding hashes for later
* retrieval */
private byte[] codeHash = EMPTY_DATA_HASH;
@ -53,7 +53,7 @@ public class AccountState {
this.nonce = nonce;
this.balance = balance;
}
public AccountState(byte[] rlpData) {
this.rlpEncoded = rlpData;
@ -115,7 +115,7 @@ public class AccountState {
this.balance = balance.subtract(value);
setDirty(true);
}
public byte[] getEncoded() {
if(rlpEncoded == null) {
byte[] nonce = RLP.encodeBigInteger(this.nonce);

View File

@ -16,10 +16,10 @@ import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* The block in Ethereum is the collection of relevant pieces of information
* The block in Ethereum is the collection of relevant pieces of information
* (known as the blockheader), H, together with information corresponding to
* the comprised transactions, R, and a set of other blockheaders U that are known
* to have a parent equal to the present blocks parents parent
* the comprised transactions, R, and a set of other blockheaders U that are known
* to have a parent equal to the present blocks parents parent
* (such blocks are known as uncles).
*
* www.ethereumJ.com
@ -30,7 +30,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
public class Block {
private static final Logger logger = LoggerFactory.getLogger("block");
public static BigInteger BLOCK_REWARD = BigInteger.valueOf(1500000000000000000L);
public static BigInteger UNCLE_REWARD = BLOCK_REWARD.multiply(
BigInteger.valueOf(15)).divide(BigInteger.valueOf(16));
@ -38,28 +38,28 @@ public class Block {
.divide(BigInteger.valueOf(32));
private BlockHeader header;
/* Transactions */
private List<Transaction> transactionsList = new CopyOnWriteArrayList<>();
/* Uncles */
private List<BlockHeader> uncleList = new CopyOnWriteArrayList<>();
/* Private */
/* Private */
private byte[] rlpEncoded;
private boolean parsed = false;
private Trie txsState;
/* Constructors */
public Block(byte[] rawData) {
logger.debug("new from [" + Hex.toHexString(rawData) + "]");
this.rlpEncoded = rawData;
this.parsed = false;
}
public Block(byte[] parentHash, byte[] unclesHash, byte[] coinbase, byte[] logsBloom,
byte[] difficulty, long number, long gasLimit,
long gasUsed, long timestamp, byte[] extraData, byte[] nonce,
@ -85,11 +85,11 @@ public class Block {
RLPList params = RLP.decode2(rlpEncoded);
RLPList block = (RLPList) params.get(0);
// Parse Header
RLPList header = (RLPList) block.get(0);
this.header = new BlockHeader(header);
// Parse Transactions
RLPList txTransactions = (RLPList) block.get(1);
this.parseTxs(this.header.getTxTrieRoot(), txTransactions);
@ -131,7 +131,7 @@ public class Block {
return FastByteComparisons.compareTo(result, 0, 32, target, 0, 32) < 0;
}
public byte[] getParentHash() {
if (!parsed) parseRLP();
return this.header.getParentHash();
@ -151,7 +151,7 @@ public class Block {
if (!parsed) parseRLP();
return this.header.getStateRoot();
}
public void setStateRoot(byte[] stateRoot) {
if (!parsed) parseRLP();
this.header.setStateRoot(stateRoot);
@ -180,12 +180,12 @@ public class Block {
}
return calcDifficulty;
}
public long getTimestamp() {
if (!parsed) parseRLP();
return this.header.getTimestamp();
}
public long getNumber() {
if (!parsed) parseRLP();
return this.header.getNumber();
@ -210,7 +210,7 @@ public class Block {
if (!parsed) parseRLP();
return this.header.getNonce();
}
public void setNonce(byte[] nonce) {
this.header.setNonce(nonce);
rlpEncoded = null;
@ -228,7 +228,7 @@ public class Block {
private StringBuffer toStringBuff = new StringBuffer();
// [parent_hash, uncles_hash, coinbase, state_root, tx_trie_root,
// difficulty, number, minGasPrice, gasLimit, gasUsed, timestamp,
// difficulty, number, minGasPrice, gasLimit, gasUsed, timestamp,
// extradata, nonce]
@Override
@ -260,7 +260,7 @@ public class Block {
toStringBuff.append("BlockData [");
toStringBuff.append("hash=" + ByteUtil.toHexString(this.getHash())).append("");
toStringBuff.append(header.toFlatString());
for (Transaction tx : getTransactionsList()) {
toStringBuff.append("\n");
toStringBuff.append(tx.toString());
@ -318,7 +318,7 @@ public class Block {
this.getHeader().setUnclesHash( SHA3Helper.sha3( getUnclesEncoded() ));
rlpEncoded = null;
}
public byte[] getEncoded() {
if(rlpEncoded == null) {
byte[] header = this.header.getEncoded();
@ -328,7 +328,7 @@ public class Block {
}
return rlpEncoded;
}
public byte[] getEncodedWithoutNonce() {
if (!parsed) parseRLP();
byte[] header = this.header.getEncodedWithoutNonce();

View File

@ -11,23 +11,23 @@ import static org.ethereum.crypto.HashUtil.EMPTY_TRIE_HASH;
import static org.ethereum.util.ByteUtil.toHexString;
/**
* Block header is a value object containing
* the basic information of a block
* Block header is a value object containing
* the basic information of a block
*/
public class BlockHeader {
/* The SHA3 256-bit hash of the parent block, in its entirety */
private byte[] parentHash;
/* The SHA3 256-bit hash of the uncles list portion of this block */
private byte[] unclesHash;
/* The 160-bit address to which all fees collected from the
/* The 160-bit address to which all fees collected from the
* successful mining of this block be transferred; formally */
private byte[] coinbase;
/* The SHA3 256-bit hash of the root node of the state trie,
/* The SHA3 256-bit hash of the root node of the state trie,
* after all transactions are executed and finalisations applied */
private byte[] stateRoot;
/* The SHA3 256-bit hash of the root node of the trie structure
/* The SHA3 256-bit hash of the root node of the trie structure
* populated with each transaction in the transaction
* list portion, the trie is populate by [key, val] --> [rlp(index), rlp(tx_reciepe)]
* of the block */
@ -41,33 +41,33 @@ public class BlockHeader {
/*todo: comment it when you know what the fuck it is*/
private byte[] logsBloom;
/* A scalar value corresponding to the difficulty level of this block.
* This can be calculated from the previous blocks difficulty level
* This can be calculated from the previous blocks difficulty level
* and the timestamp */
private byte[] difficulty;
/* A scalar value equal to the reasonable output of Unix's time()
/* A scalar value equal to the reasonable output of Unix's time()
* at this block's inception */
private long timestamp;
/* A scalar value equal to the number of ancestor blocks.
private long timestamp;
/* A scalar value equal to the number of ancestor blocks.
* The genesis block has a number of zero */
private long number;
/* A scalar value equal to the current limit of gas expenditure per block */
private long gasLimit;
/* A scalar value equal to the total gas used in transactions in this block */
private long gasUsed;
/* An arbitrary byte array containing data relevant to this block.
/* An arbitrary byte array containing data relevant to this block.
* With the exception of the genesis block, this must be 32 bytes or fewer */
private byte[] extraData;
/* A 256-bit hash which proves that a sufficient amount
/* A 256-bit hash which proves that a sufficient amount
* of computation has been carried out on this block */
private byte[] nonce;
public BlockHeader(RLPList rlpHeader) {
this.parentHash = rlpHeader.get(0).getRLPData();
this.unclesHash = rlpHeader.get(1).getRLPData();
this.coinbase = rlpHeader.get(2).getRLPData();
this.stateRoot = rlpHeader.get(3).getRLPData();
this.txTrieRoot = rlpHeader.get(4).getRLPData();
if(this.txTrieRoot == null)
this.txTrieRoot = EMPTY_TRIE_HASH;
@ -78,23 +78,23 @@ public class BlockHeader {
this.logsBloom = rlpHeader.get(6).getRLPData();
this.difficulty = rlpHeader.get(7).getRLPData();
byte[] nrBytes = rlpHeader.get(8).getRLPData();
byte[] glBytes = rlpHeader.get(9).getRLPData();
byte[] guBytes = rlpHeader.get(10).getRLPData();
byte[] tsBytes = rlpHeader.get(11).getRLPData();
this.number = nrBytes == null ? 0 : (new BigInteger(1, nrBytes)).longValue();
this.gasLimit = glBytes == null ? 0 : (new BigInteger(1, glBytes)).longValue();
this.gasUsed = guBytes == null ? 0 : (new BigInteger(1, guBytes)).longValue();
this.timestamp = tsBytes == null ? 0 : (new BigInteger(1, tsBytes)).longValue();
this.extraData = rlpHeader.get(12).getRLPData();
this.nonce = rlpHeader.get(13).getRLPData();
}
public BlockHeader(byte[] parentHash, byte[] unclesHash, byte[] coinbase,
byte[] logsBloom, byte[] difficulty, long number,
long gasLimit, long gasUsed, long timestamp,
@ -112,10 +112,10 @@ public class BlockHeader {
this.nonce = nonce;
this.stateRoot = HashUtil.EMPTY_TRIE_HASH;
}
/**
* Calculate Difficulty
* Calculate Difficulty
* See Yellow Paper: http://www.gavwood.com/Paper.pdf - page 5, 4.3.4 (24)
* @return byte array value of the difficulty
*/
@ -217,15 +217,15 @@ public class BlockHeader {
public void setNonce(byte[] nonce) {
this.nonce = nonce;
}
public byte[] getEncoded() {
return this.getEncoded(true); // with nonce
}
public byte[] getEncodedWithoutNonce() {
return this.getEncoded(false);
}
public byte[] getEncoded(boolean withNonce) {
byte[] parentHash = RLP.encodeElement(this.parentHash);
@ -262,7 +262,7 @@ public class BlockHeader {
private StringBuffer toStringBuff = new StringBuffer();
public String toString() {
toStringBuff.setLength(0);
@ -281,7 +281,7 @@ public class BlockHeader {
toStringBuff.append(" nonce=" + toHexString(nonce)).append("\n");
return toStringBuff.toString();
}
public String toFlatString() {
toStringBuff.append(" parentHash=" + toHexString(parentHash)).append("");
toStringBuff.append(" unclesHash=" + toHexString(unclesHash)).append("");

View File

@ -29,14 +29,14 @@ import static org.ethereum.config.SystemProperties.CONFIG;
import static org.ethereum.core.Denomination.SZABO;
/**
* The Ethereum blockchain is in many ways similar to the Bitcoin blockchain,
* although it does have some differences.
*
* The main difference between Ethereum and Bitcoin with regard to the blockchain architecture
* is that, unlike Bitcoin, Ethereum blocks contain a copy of both the transaction list
* and the most recent state. Aside from that, two other values, the block number and
* the difficulty, are also stored in the block.
*
* The Ethereum blockchain is in many ways similar to the Bitcoin blockchain,
* although it does have some differences.
*
* The main difference between Ethereum and Bitcoin with regard to the blockchain architecture
* is that, unlike Bitcoin, Ethereum blocks contain a copy of both the transaction list
* and the most recent state. Aside from that, two other values, the block number and
* the difficulty, are also stored in the block.
*
* The block validation algorithm in Ethereum is as follows:
* <ol>
* <li>Check if the previous block referenced exists and is valid.</li>
@ -44,9 +44,9 @@ import static org.ethereum.core.Denomination.SZABO;
* <li>Check that the block number, difficulty, transaction root, uncle root and gas limit (various low-level Ethereum-specific concepts) are valid.</li>
* <li>Check that the proof of work on the block is valid.</li>
* <li>Let S[0] be the STATE_ROOT of the previous block.</li>
* <li>Let TX be the block's transaction list, with n transactions.
* For all in in 0...n-1, set S[i+1] = APPLY(S[i],TX[i]).
* If any applications returns an error, or if the total gas consumed in the block
* <li>Let TX be the block's transaction list, with n transactions.
* For all in in 0...n-1, set S[i+1] = APPLY(S[i],TX[i]).
* If any applications returns an error, or if the total gas consumed in the block
* up until this point exceeds the GASLIMIT, return an error.</li>
* <li>Let S_FINAL be S[n], but adding the block reward paid to the miner.</li>
* <li>Check if S_FINAL is the same as the STATE_ROOT. If it is, the block is valid; otherwise, it is not valid.</li>
@ -66,7 +66,7 @@ public class BlockchainImpl implements Blockchain {
private static final Logger logger = LoggerFactory.getLogger("blockchain");
private static final Logger stateLogger = LoggerFactory.getLogger("state");
// to avoid using minGasPrice=0 from Genesis for the wallet
private static final long INITIAL_MIN_GAS_PRICE = 10 * SZABO.longValue();
@ -107,7 +107,7 @@ public class BlockchainImpl implements Blockchain {
public byte[] getBestBlockHash() {
return getBestBlock().getHash();
}
@Override
public long getSize() {
return bestBlock.getNumber() + 1;
@ -313,7 +313,7 @@ public class BlockchainImpl implements Blockchain {
logger.warn("Invalid block with nr: {}", block.getNumber());
}
}
private List<TransactionReceipt> applyBlock(Block block) {
int i = 1;
@ -363,15 +363,15 @@ public class BlockchainImpl implements Blockchain {
/**
* Add reward to block- and every uncle coinbase
* assuming the entire block is valid.
*
*
* @param block object containing the header and uncles
*/
private void addReward(Block block) {
// Add standard block reward
BigInteger totalBlockReward = Block.BLOCK_REWARD;
// Add extra rewards based on number of uncles
// Add extra rewards based on number of uncles
if(block.getUncleList().size() > 0) {
for (BlockHeader uncle : block.getUncleList()) {
track.addBalance(uncle.getCoinbase(), Block.UNCLE_REWARD);
@ -381,7 +381,7 @@ public class BlockchainImpl implements Blockchain {
}
track.addBalance(block.getCoinbase(), totalBlockReward);
}
@Override
public void storeBlock(Block block, List<TransactionReceipt> receipts) {
@ -408,8 +408,8 @@ public class BlockchainImpl implements Blockchain {
logger.debug("block added to the blockChain: index: [{}]", block.getNumber());
if (block.getNumber() % 100 == 0)
logger.info("*** Last block added [ #{} ]", block.getNumber());
}
}
public boolean hasParentOnTheChain(Block block){
return getParent(block.getHeader()) != null;

View File

@ -12,10 +12,10 @@ public enum Denomination {
FINNY(newBigInt(15)),
ETHER(newBigInt(18)),
EINSTEIN(newBigInt(21)),
DOUGLAS(newBigInt(42));
DOUGLAS(newBigInt(42));
private BigInteger amount;
private Denomination(BigInteger value) {
this.amount = value;
}
@ -23,7 +23,7 @@ public enum Denomination {
public BigInteger value() {
return amount;
}
public long longValue() {
return value().longValue();
}
@ -31,7 +31,7 @@ public enum Denomination {
private static BigInteger newBigInt(int value) {
return BigInteger.valueOf(10).pow(value);
}
public static String toFriendlyString(BigInteger value) {
if(value.compareTo(DOUGLAS.value()) == 1 || value.compareTo(DOUGLAS.value()) == 0) {
return Float.toString(value.divide(DOUGLAS.value()).floatValue()) + " DOUGLAS";

View File

@ -10,26 +10,26 @@ import org.ethereum.trie.TrieImpl;
import org.spongycastle.util.encoders.Hex;
/**
* The genesis block is the first block in the chain and has fixed values according to
* 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.
*
* - 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 {
public final static BigInteger PREMINE_AMOUNT = BigInteger.valueOf(2).pow(200);
private static String[] premine = new String[] {
"51ba59315b3a95761d0863b05ccc7a7f54703d99",
"e6716f9544a56c530d868e4bfbacb172315bdead", // # (J)
@ -56,14 +56,14 @@ public class Genesis extends Block {
public static long TIMESTAMP = 0;
public static byte[] EXTRA_DATA = new byte[0];
public static byte[] NONCE = sha3(new byte[]{42});
private static Block instance;
private Genesis() {
super(PARENT_HASH, UNCLES_HASH, COINBASE, LOG_BLOOM, DIFFICULTY,
NUMBER, GAS_LIMIT, GAS_USED, TIMESTAMP,
EXTRA_DATA, NONCE, null, null);
Trie state = new TrieImpl(null);
// The proof-of-concept series include a development pre-mine, making the state root hash
// some value stateRoot. The latest documentation should be consulted for the value of the state root.
@ -74,14 +74,14 @@ public class Genesis extends Block {
setStateRoot(state.getRootHash());
}
public static Block getInstance() {
if (instance == null) {
instance = new Genesis();
}
return instance;
}
public final static String[] getPremine() {
return premine;
}

View File

@ -16,17 +16,17 @@ import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY;
import static org.ethereum.util.ByteUtil.ZERO_BYTE_ARRAY;
/**
* 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.
* There are two types of transactions: those which result in message calls
* 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.
* There are two types of transactions: those which result in message calls
* and those which result in the creation of new contracts.
*/
public class Transaction {
private static final Logger logger = LoggerFactory.getLogger(Transaction.class);
/* SHA3 hash of the RLP encoded transaction */
private byte[] hash;
@ -64,7 +64,7 @@ public class Transaction {
/* Tx in encoded form */
private byte[] rlpEncoded;
private byte[] rlpRaw;
/* Indicates if this transaction has been parsed
/* Indicates if this transaction has been parsed
* from the RLP-encoded data */
private boolean parsed = false;
@ -295,7 +295,7 @@ public class Transaction {
byte[] data = RLP.encodeElement(this.data);
byte[] v, r, s;
if(signature != null) {
v = RLP.encodeByte( signature.v );
r = RLP.encodeElement(BigIntegers.asUnsignedByteArray(signature.r));

View File

@ -13,9 +13,9 @@ import java.util.List;
import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY;
/**
* The transaction receipt is a tuple of three items
* comprising the transaction, together with the post-transaction state,
* and the cumulative gas used in the block containing the transaction receipt
* The transaction receipt is a tuple of three items
* comprising the transaction, together with the post-transaction state,
* and the cumulative gas used in the block containing the transaction receipt
* as of immediately after the transaction has happened,
*
*

View File

@ -40,7 +40,7 @@ public class Wallet {
// TODO: a) the values I need to keep for address state is balance & nonce & ECKey
// TODO: b) keep it to be easy accessed by the toAddress()
// private HashMap<Address, BigInteger> rows = new HashMap<>();
// This map of transaction designed
// to approve the tx by external trusted peer
private Map<String, WalletTransaction> walletTransactions = new ConcurrentHashMap<>();
@ -141,13 +141,13 @@ public class Wallet {
return walletTransaction;
}
public void addTransactions(List<Transaction> transactions) {
for (Transaction transaction : transactions) {
this.addTransaction(transaction);
}
}
public void removeTransactions(List<Transaction> transactions) {
for (Transaction tx : transactions) {
if (logger.isDebugEnabled())
@ -182,7 +182,7 @@ public class Wallet {
Account receiver = rows.get(Hex.toHexString(receiveAddress));
if (receiver != null) {
receiver.addPendingTransaction(transaction);
logger.info("Pending transaction added to " +
"\n account: [{}], " +
"\n tx: [{}]",
@ -221,7 +221,7 @@ public class Wallet {
<value>900099909<value/>
</row>
</wallet>
*/
String dir = System.getProperty("user.dir");

View File

@ -50,7 +50,7 @@ import org.spongycastle.util.encoders.Hex;
* Creating a new ECKey with the empty constructor will generate a new random keypair. Other static methods can be used
* when you already have the public or private parts. If you create a key with only the public part, you can check
* signatures but not create them.</p>
*
*
* <p>The ECDSA algorithm supports <i>key recovery</i> in which a signature plus a couple of discriminator bits can
* be reversed to find the public key used to calculate it. This can be convenient when you have a message and a
* signature and want to find out who signed it, rather than requiring the user to provide the expected identity.</p>
@ -70,7 +70,7 @@ import org.spongycastle.util.encoders.Hex;
*/
public class ECKey implements Serializable {
private static final Logger logger = LoggerFactory.getLogger(ECKey.class);
/** The parameters of the secp256k1 curve that Ethereum uses. */
public static final ECDomainParameters CURVE;
@ -90,7 +90,7 @@ public class ECKey implements Serializable {
HALF_CURVE_ORDER = params.getN().shiftRight(1);
secureRandom = new SecureRandom();
}
// The two parts of the key. If "priv" is set, "pub" can always be calculated. If "pub" is set but not "priv", we
// can only verify signatures not make them.
// TODO: Redesign this class to use consistent internals and more efficient serialization.
@ -129,7 +129,7 @@ public class ECKey implements Serializable {
throw new IllegalArgumentException("Public key may not be null");
this.pub = pub;
}
/**
* Utility for compressing an elliptic curve point. Returns the same point if it's already compressed.
* See the ECKey class docs for a discussion of point compression.
@ -145,7 +145,7 @@ public class ECKey implements Serializable {
public static ECPoint decompressPoint(ECPoint compressed) {
return CURVE.getCurve().decodePoint(compressed.getEncoded(false));
}
/**
* Creates an ECKey given the private key only. The public key is calculated from it (this is slow). Note that
* the resulting public key is compressed.
@ -197,7 +197,7 @@ public class ECKey implements Serializable {
public static ECKey fromPublicOnly(byte[] pub) {
return new ECKey(null, CURVE.getCurve().decodePoint(pub));
}
/**
* Returns a copy of this key, but with the public point represented in uncompressed form. Normally you would
* never need this: it's for specialised scenarios or when backwards compatibility in encoded form is necessary.
@ -224,7 +224,7 @@ public class ECKey implements Serializable {
public boolean hasPrivKey() {
return priv != null;
}
/**
* Returns public key bytes from the given private key. To convert a byte array into a BigInteger, use <tt>
* new BigInteger(1, bytes);</tt>
@ -293,7 +293,7 @@ public class ECKey implements Serializable {
}
return b.toString();
}
/**
* Groups the two components that make up a signature, and provides a way to encode to Base64 form, which is
* how ECDSA signatures are represented when embedded in other data structures in the Ethereum protocol. The raw
@ -311,11 +311,11 @@ public class ECKey implements Serializable {
this.r = r;
this.s = s;
}
private static ECDSASignature fromComponents(byte[] r, byte[] s) {
return new ECDSASignature(new BigInteger(1, r), new BigInteger(1, s));
}
public static ECDSASignature fromComponents(byte[] r, byte[] s, byte v) {
ECDSASignature signature = fromComponents(r, s);
signature.v = v;
@ -341,7 +341,7 @@ public class ECKey implements Serializable {
return this;
}
}
public String toBase64() {
byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 bytes for S
sigData[0] = v;
@ -349,7 +349,7 @@ public class ECKey implements Serializable {
System.arraycopy(bigIntegerToBytes(this.s, 32), 0, sigData, 33, 32);
return new String(Base64.encode(sigData), Charset.forName("UTF-8"));
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@ -370,11 +370,11 @@ public class ECKey implements Serializable {
return result;
}
}
/**
* Signs the given hash and returns the R and S components as BigIntegers
* and put them in ECDSASignature
*
* Signs the given hash and returns the R and S components as BigIntegers
* and put them in ECDSASignature
*
* @param input to sign
* @return ECDSASignature signature that contains the R and S components
*/
@ -389,7 +389,7 @@ public class ECKey implements Serializable {
BigInteger[] components = signer.generateSignature(input);
return new ECDSASignature(components[0], components[1]).toCanonicalised();
}
/**
* Takes the sha3 hash (32 bytes) of data and returns the ECDSA signature
*
@ -413,12 +413,12 @@ public class ECKey implements Serializable {
sig.v = (byte) (recId + 27 + (isCompressed() ? 4 : 0));
return sig;
}
/**
* Given a piece of text and a message signature encoded in base64, returns an ECKey
* containing the public key that was used to sign it. This can then be compared to the expected public key to
* determine if the signature was correct.
*
*
* @param messageHash a piece of human readable text that was signed
* @param signatureBase64 The Ethereum-format message signature in base64
* @throws SignatureException If the public key could not be recovered or if there was a signature format error.
@ -453,10 +453,10 @@ public class ECKey implements Serializable {
throw new SignatureException("Could not recover public key from signature");
return key;
}
/**
* <p>Verifies the given ECDSA signature against the message bytes using the public key bytes.</p>
*
*
* <p>When using native ECDSA verification, data must be 32 bytes, and no element may be
* larger than 520 bytes.</p>
*
@ -471,7 +471,7 @@ public class ECKey implements Serializable {
try {
return signer.verifySignature(data, signature.r, signature.s);
} catch (NullPointerException npe) {
// Bouncy Castle contains a bug that can cause NPEs given specially crafted signatures.
// Bouncy Castle contains a bug that can cause NPEs given specially crafted signatures.
// Those signatures are inherently invalid/attack sigs so we just fail them here rather than crash the thread.
logger.error("Caught NPE inside bouncy castle", npe);
return false;
@ -637,7 +637,7 @@ public class ECKey implements Serializable {
byte[] bits = getPubKey();
return (bits[0] & 0xFF) | ((bits[1] & 0xFF) << 8) | ((bits[2] & 0xFF) << 16) | ((bits[3] & 0xFF) << 24);
}
@SuppressWarnings("serial")
public static class MissingPrivateKeyException extends RuntimeException {
}

View File

@ -18,14 +18,14 @@ import org.ethereum.util.LRUMap;
public class HashUtil {
private static final int MAX_ENTRIES = 100; // Should contain most commonly hashed values
private static final int MAX_ENTRIES = 100; // Should contain most commonly hashed values
private static LRUMap<ByteArrayWrapper, byte[]> sha3Cache = new LRUMap<>(0, MAX_ENTRIES);
public static final byte[] EMPTY_DATA_HASH = sha3(EMPTY_BYTE_ARRAY);
public static final byte[] EMPTY_LIST_HASH = sha3(RLP.encodeList());
public static final byte[] EMPTY_TRIE_HASH = sha3(RLP.encodeElement(EMPTY_BYTE_ARRAY));
private static final MessageDigest sha256digest;
static {
try {
sha256digest = MessageDigest.getInstance("SHA-256");
@ -33,7 +33,7 @@ public class HashUtil {
throw new RuntimeException(e); // Can't happen.
}
}
public static byte[] sha256(byte[] input) {
return sha256digest.digest(input);
}
@ -47,7 +47,7 @@ public class HashUtil {
sha3Cache.put(inputByteArray, result);
return result;
}
public static byte[] ripemd160(byte[] message) {
Digest digest = new RIPEMD160Digest();
if (message != null) {
@ -83,7 +83,7 @@ public class HashUtil {
return newAddress;
}
/**
* @see #doubleDigest(byte[], int, int)
*/

View File

@ -6,9 +6,9 @@ import org.spongycastle.crypto.digests.SHA3Digest;
import org.spongycastle.util.encoders.Hex;
public class SHA3Helper {
private static int DEFAULT_SIZE = 256;
public static String sha3String(String message) {
return sha3String(message, new SHA3Digest(DEFAULT_SIZE), true);
}
@ -75,23 +75,23 @@ public class SHA3Helper {
digest.doFinal(hash, 0);
return hash;
}
public enum Size {
S224(224),
S256(256),
S384(384),
S512(512);
int bits = 0;
Size(int bits) {
this.bits = bits;
}
public int getValue() {
return this.bits;
}
}
}

View File

@ -24,7 +24,7 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper> {
return false;
byte[] otherData = ((ByteArrayWrapper) other).getData();
return FastByteComparisons.compareTo(
data, 0, data.length,
data, 0, data.length,
otherData, 0, otherData.length) == 0;
}
@ -36,10 +36,10 @@ public class ByteArrayWrapper implements Comparable<ByteArrayWrapper> {
@Override
public int compareTo(ByteArrayWrapper o) {
return FastByteComparisons.compareTo(
data, 0, data.length,
data, 0, data.length,
o.getData(), 0, o.getData().length);
}
public byte[] getData() {
return data;
}

View File

@ -32,7 +32,7 @@ public class ContractDetails {
public ContractDetails() {
}
public ContractDetails(byte[] rlpCode) {
decode(rlpCode);
}

View File

@ -4,26 +4,26 @@ package org.ethereum.db;
* Ethereum generic database interface
*/
public interface Database {
/**
/**
* Get value from database
*
*
* @param key for which to retrieve the value
* @return the value for the given key
*/
public byte[] get(byte[] key);
/**
* Insert value into database
*
*
* @param key for the given value
* @param value to insert
*/
public void put(byte[] key, byte[] value);
public void put(byte[] key, byte[] value);
/**
* Delete key/value pair from database
*
*
* @param key for which to delete the value
*/
public void delete(byte[] key);

View File

@ -19,18 +19,18 @@ import org.spongycastle.util.encoders.Hex;
/**
* Generic interface for Ethereum database
*
*
* LevelDB key/value pair DB implementation will be used.
* Choice must be made between:
* Pure Java: https://github.com/dain/leveldb
* JNI binding: https://github.com/fusesource/leveldbjni
*/
public class DatabaseImpl implements Database {
private static final Logger logger = LoggerFactory.getLogger("db");
private DB db;
private String name;
public DatabaseImpl(String name) {
// Initialize Database
this.name = name;
@ -69,9 +69,9 @@ public class DatabaseImpl implements Database {
} catch (IOException ioe) {
logger.error(ioe.getMessage(), ioe);
throw new RuntimeException("Can't initialize database");
}
}
}
public void destroyDB(File fileLocation) {
logger.debug("Destroying existing database");
Options options = new Options();
@ -81,12 +81,12 @@ public class DatabaseImpl implements Database {
logger.error(e.getMessage(), e);
}
}
@Override
public byte[] get(byte[] key) {
return db.get(key);
}
@Override
public void put(byte[] key, byte[] value) {
@ -96,7 +96,7 @@ public class DatabaseImpl implements Database {
Hex.toHexString(value));
db.put(key, value);
}
@Override
public void delete(byte[] key) {
if(logger.isDebugEnabled())
@ -104,11 +104,11 @@ public class DatabaseImpl implements Database {
db.delete(key);
}
public DBIterator iterator() {
return db.iterator();
}
public DB getDb() {
return this.db;
}

View File

@ -21,7 +21,7 @@ public interface Repository {
/**
* Create a new account in the database
*
*
* @param addr of the contract
* @return newly created account state
*/
@ -34,65 +34,65 @@ public interface Repository {
* false otherwise
*/
public boolean isExist(byte[] addr);
/**
* Retrieve an account
*
*
* @param addr of the account
* @return account state as stored in the database
*/
public AccountState getAccountState(byte[] addr);
/**
* Deletes the account
*
*
* @param addr of the account
*/
public void delete(byte[] addr);
/**
* Increase the account nonce of the given account by one
*
*
* @param addr of the account
* @return new value of the nonce
*/
public BigInteger increaseNonce(byte[] addr);
/**
* Get current nonce of a given account
*
*
* @param addr of the account
* @return value of the nonce
*/
public BigInteger getNonce(byte[] addr);
/**
* Retrieve contract details for a given account from the database
*
*
* @param addr of the account
* @return new contract details
* @return new contract details
*/
public ContractDetails getContractDetails(byte[] addr);
/**
* Store code associated with an account
*
*
* @param addr for the account
* @param code that will be associated with this account
*/
public void saveCode(byte[] addr, byte[] code);
/**
* Retrieve the code associated with an account
*
*
* @param addr of the account
* @return code in byte-array format
*/
public byte[] getCode(byte[] addr);
/**
* Put a value in storage of an account at a given key
*
*
* @param addr of the account
* @param key of the data to store
* @param value is the data to store
@ -102,34 +102,34 @@ public interface Repository {
/**
* Retrieve storage value from an account for a given key
*
*
* @param addr of the account
* @param key associated with this value
* @return data in the form of a <code>DataWord</code>
*/
public DataWord getStorageValue(byte[] addr, DataWord key);
/**
* Retrieve balance of an account
*
*
* @param addr of the account
* @return balance of the account as a <code>BigInteger</code> value
*/
public BigInteger getBalance(byte[] addr);
/**
* Add value to the balance of an account
*
*
* @param addr of the account
* @param value to be added
* @return new balance of the account
*/
public BigInteger addBalance(byte[] addr, BigInteger value);
/**
* Returns an iterator over the accounts in this database in proper sequence
*
*
* @return an iterator over the accounts in this database in proper sequence
*/
public DBIterator getAccountsIterator();
@ -137,12 +137,12 @@ public interface Repository {
/**
* Dump the full state of the current repository into a file with JSON format
* It contains all the contracts/account, their attributes and
*
* It contains all the contracts/account, their attributes and
*
* @param block of the current state
* @param gasUsed the amount of gas used in the block until that point
* @param txNumber is the number of the transaction for which the dump has to be made
* @param txHash is the hash of the given transaction.
* @param txHash is the hash of the given transaction.
* If null, the block state post coinbase reward is dumped.
*/
public void dumpState(Block block, long gasUsed, int txNumber, byte[] txHash);
@ -158,13 +158,13 @@ public interface Repository {
/**
* Store all the temporary changes made
* Store all the temporary changes made
* to the repository in the actual database
*/
public void commit();
/**
* Undo all the changes made so far
* Undo all the changes made so far
* to a snapshot of the repository
*/
public void rollback();
@ -175,13 +175,13 @@ public interface Repository {
* @param root - new root
*/
public void syncToRoot(byte[] root);
/**
* Check to see if the current repository has an open connection to the database
* @return <tt>true</tt> if connection to database is open
*/
public boolean isClosed();
/**
* Close the database
*/

View File

@ -11,9 +11,9 @@ import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* An extended {@link com.fasterxml.jackson.databind.ObjectMapper ObjectMapper} class to
* An extended {@link com.fasterxml.jackson.databind.ObjectMapper ObjectMapper} class to
* customize ethereum state dumps.
*
*
* @author Alon Muroch
*
*/
@ -21,7 +21,7 @@ public class EtherObjectMapper extends ObjectMapper {
@Override
public String writeValueAsString(Object value)
throws JsonProcessingException {
throws JsonProcessingException {
// alas, we have to pull the recycler directly here...
SegmentedStringWriter sw = new SegmentedStringWriter(_jsonFactory._getBufferRecycler());
try {
@ -29,7 +29,7 @@ public class EtherObjectMapper extends ObjectMapper {
// set ethereum custom pretty printer
EtherPrettyPrinter pp = new EtherPrettyPrinter();
ge.setPrettyPrinter(pp);
_configAndWriteValue(ge, value);
} catch (JsonProcessingException e) { // to support [JACKSON-758]
throw e;
@ -38,11 +38,11 @@ public class EtherObjectMapper extends ObjectMapper {
}
return sw.getAndClear();
}
/**
* An extended {@link com.fasterxml.jackson.core.util.DefaultPrettyPrinter} class to customize
* An extended {@link com.fasterxml.jackson.core.util.DefaultPrettyPrinter} class to customize
* an ethereum {@link com.fasterxml.jackson.core.PrettyPrinter Pretty Printer} Generator
*
*
* @author Alon Muroch
*
*/
@ -51,7 +51,7 @@ public class EtherObjectMapper extends ObjectMapper {
public EtherPrettyPrinter() {
super();
}
@Override
public void writeObjectFieldValueSeparator(JsonGenerator jg)
throws IOException, JsonGenerationException {

View File

@ -16,26 +16,26 @@ import java.math.BigInteger;
import java.util.*;
/**
* JSON Helper class to format data into ObjectNodes
* JSON Helper class to format data into ObjectNodes
* to match PyEthereum blockstate output
*
*
* Dump format:
* {
* "address":
* {
* "nonce": "n1",
* "balance": "b1",
* "stateRoot": "s1",
* "codeHash": "c1",
* "code": "c2",
* "storage":
* {
* "key1": "value1",
* "key2": "value2"
* "address":
* {
* "nonce": "n1",
* "balance": "b1",
* "stateRoot": "s1",
* "codeHash": "c1",
* "code": "c2",
* "storage":
* {
* "key1": "value1",
* "key2": "value2"
* }
* }
* }
*
*
* www.ethereumJ.com
*
* @author: Roman Mandeleil
@ -43,14 +43,14 @@ import java.util.*;
*/
public class JSONHelper {
public static void dumpState(ObjectNode statesNode, String address, AccountState state, ContractDetails details) {
public static void dumpState(ObjectNode statesNode, String address, AccountState state, ContractDetails details) {
List<DataWord> storageKeys = new ArrayList<>(details.getStorage().keySet());
Collections.sort((List<DataWord>) storageKeys);
ObjectNode account = statesNode.objectNode();
ObjectNode storage = statesNode.objectNode();
for (DataWord key : storageKeys) {
storage.put("0x" + Hex.toHexString(key.getData()),
"0x" + Hex.toHexString(details.getStorage().get(key).getNoLeadZeroesData()));
@ -61,14 +61,14 @@ public class JSONHelper {
account.put("nonce", state.getNonce() == null ? "0" : state.getNonce().toString());
account.put("storage", storage);
account.put("storage_root", state.getStateRoot() == null ? "" : Hex.toHexString(state.getStateRoot()));
statesNode.put(address, account);
}
public static void dumpBlock(ObjectNode blockNode, Block block,
long gasUsed, byte[] state, List<ByteArrayWrapper> keys,
Repository repository) {
blockNode.put("coinbase", Hex.toHexString(block.getCoinbase()));
blockNode.put("difficulty", new BigInteger(1, block.calcDifficulty()).toString());
blockNode.put("extra_data", "0x");
@ -76,25 +76,25 @@ public class JSONHelper {
blockNode.put("nonce", "0x" + Hex.toHexString(block.getNonce()));
blockNode.put("number", String.valueOf(block.getNumber()));
blockNode.put("prevhash", "0x" + Hex.toHexString(block.getParentHash()));
ObjectNode statesNode = blockNode.objectNode();
for (ByteArrayWrapper key : keys) {
byte[] keyBytes = key.getData();
AccountState accountState = repository.getAccountState(keyBytes);
ContractDetails details = repository.getContractDetails(keyBytes);
JSONHelper.dumpState(statesNode, Hex.toHexString(keyBytes), accountState, details);
}
}
blockNode.put("state", statesNode);
blockNode.put("state_root", Hex.toHexString(state));
blockNode.put("timestamp", String.valueOf(block.getTimestamp()));
ArrayNode transactionsNode = blockNode.arrayNode();
blockNode.put("transactions", transactionsNode);
blockNode.put("tx_list_root", ByteUtil.toHexString(block.getTxTrieRoot()));
blockNode.put("uncles_hash", "0x" + Hex.toHexString(block.getUnclesHash()));
// JSONHelper.dumpTransactions(blockNode,
// stateRoot, codeHash, code, storage);
}

View File

@ -20,7 +20,7 @@ public class JSONReader {
json = getFromUrl("https://raw.githubusercontent.com/ethereum/tests/develop/" + filename);
return json == "" ? json = getFromLocal(filename) : json;
}
public static String getFromLocal(String filename) {
System.out.println("Loading local file: " + filename);
try {
@ -36,7 +36,7 @@ public class JSONReader {
}
return "";
}
public static String getFromUrl(String urlToRead) {
URL url;
HttpURLConnection conn;

View File

@ -15,7 +15,7 @@ import org.spongycastle.util.encoders.Hex;
public class Logs {
List<LogInfo> logs = new ArrayList<>();
public Logs(JSONArray jLogs) {
for (int i = 0; i < jLogs.size(); ++i){

View File

@ -23,7 +23,7 @@ public class TestCase {
// "env": { ... },
private Env env;
//
private Logs logs;
@ -64,7 +64,7 @@ public class TestCase {
JSONArray callCreates = new JSONArray();
if(testCaseJSONObj.containsKey("callcreates"))
callCreates = (JSONArray)testCaseJSONObj.get("callcreates");
JSONArray logsJSON = new JSONArray();
if(testCaseJSONObj.containsKey("logs"))
logsJSON = (JSONArray)testCaseJSONObj.get("logs");
@ -74,7 +74,7 @@ public class TestCase {
if(testCaseJSONObj.containsKey("gas"))
gasString = testCaseJSONObj.get("gas").toString();
this.gas = ByteUtil.bigIntegerToBytes(new BigInteger(gasString));
String outString = null;
if(testCaseJSONObj.containsKey("out"))
outString = testCaseJSONObj.get("out").toString();
@ -122,7 +122,7 @@ public class TestCase {
public Exec getExec() {
return exec;
}
public Logs getLogs() {
return logs;
}

View File

@ -33,7 +33,7 @@ public class TestRunner {
private ProgramTrace trace = null;
public List<String> runTestSuite(TestSuite testSuite) {
Iterator<TestCase> testIterator = testSuite.iterator();
List<String> resultCollector = new ArrayList<>();

View File

@ -25,8 +25,8 @@ import static org.ethereum.config.SystemProperties.CONFIG;
/**
* WorldManager is a singleton containing references to different parts of the system.
*
* @author Roman Mandeleil
*
* @author Roman Mandeleil
* Created on: 01/06/2014 10:44
*/
@Component
@ -57,12 +57,12 @@ public class WorldManager {
@Autowired
private AdminInfo adminInfo;
private final Set<Transaction> pendingTransactions = Collections.synchronizedSet(new HashSet<Transaction>());
@Autowired
private EthereumListener listener;
@PostConstruct
public void init() {
byte[] cowAddr = HashUtil.sha3("cow".getBytes());
@ -72,7 +72,7 @@ public class WorldManager {
byte[] cbAddr = HashUtil.sha3(secret.getBytes());
wallet.importKey(cbAddr);
}
public void addListener(EthereumListener listener) {
logger.info("Ethereum listener added");
((EthereumListenerWrapper)this.listener).addListener(listener);
@ -115,7 +115,7 @@ public class WorldManager {
public EthereumListener getListener() {
return listener;
}
public void setWallet(Wallet wallet) {
this.wallet = wallet;
}
@ -123,11 +123,11 @@ public class WorldManager {
public Repository getRepository() {
return repository;
}
public Blockchain getBlockchain() {
return blockchain;
}
public Wallet getWallet() {
return wallet;
}

View File

@ -14,18 +14,18 @@ import java.math.BigInteger;
/**
* The Miner performs the proof-of-work needed for a valid block
*
*
* The mining proof-of-work (PoW) exists as a cryptographically secure nonce
* that proves beyond reasonable doubt that a particular amount of computation
* has been expended in the determination of some token value n.
* It is utilised to enforce the blockchain security by giving meaning
* and credence to the notion of difficulty (and, by extension, total difficulty).
*
* However, since mining new blocks comes with an attached reward,
* the proof-of-work not only functions as a method of securing confidence
* that the blockchain will remain canonical into the future, but also as
* that proves beyond reasonable doubt that a particular amount of computation
* has been expended in the determination of some token value n.
* It is utilised to enforce the blockchain security by giving meaning
* and credence to the notion of difficulty (and, by extension, total difficulty).
*
* However, since mining new blocks comes with an attached reward,
* the proof-of-work not only functions as a method of securing confidence
* that the blockchain will remain canonical into the future, but also as
* a wealth distribution mechanism.
*
*
* See Yellow Paper: http://www.gavwood.com/Paper.pdf (chapter 11.5 Mining Proof-of-Work)
*/
public class Miner {
@ -36,13 +36,13 @@ public class Miner {
/**
* Adds a nonce to given block which complies with the given difficulty
*
* For the PoC series, we use a simplified proof-of-work.
* This is not ASIC resistant and is meant merely as a placeholder.
* It utilizes the bare SHA3 hash function to secure the block chain by requiring
* the SHA3 hash of the concatenation of the nonce and the headers SHA3 hash to be
*
* For the PoC series, we use a simplified proof-of-work.
* This is not ASIC resistant and is meant merely as a placeholder.
* It utilizes the bare SHA3 hash function to secure the block chain by requiring
* the SHA3 hash of the concatenation of the nonce and the headers SHA3 hash to be
* sufficiently low. It is formally defined as PoW:
*
*
* PoW(H, n) BE(SHA3(SHA3(RLP(H!n)) n))
*
* where:
@ -54,7 +54,7 @@ public class Miner {
* o is the series concatenation operator;
* BE(X) evaluates to the value equal to X when interpreted as a
* big-endian-encoded integer.
*
*
* @param newBlock without a valid nonce
* @param difficulty - the mining difficulty
* @return true if valid nonce has been added to the block
@ -76,7 +76,7 @@ public class Miner {
byte[] testNonce = new byte[32];
byte[] concat;
while(ByteUtil.increment(testNonce) && !stop) {
if (testNonce[31] == 0 && testNonce[30] == 0){

View File

@ -18,8 +18,8 @@ import java.util.concurrent.ConcurrentLinkedQueue;
* The processing queue for blocks to be validated and added to the blockchain.
* This class also maintains the list of hashes from the peer with the heaviest sub-tree.
* Based on these hashes, blocks are added to the queue.
*
* @author Roman Mandeleil
*
* @author Roman Mandeleil
* Created on: 27/07/2014 11:28
*/
@Component
@ -27,13 +27,13 @@ public class BlockQueue {
private static final Logger logger = LoggerFactory.getLogger("blockqueue");
/** The list of hashes of the heaviest chain on the network,
/** The list of hashes of the heaviest chain on the network,
* for which this client doesn't have the blocks yet */
private Deque<byte[]> blockHashQueue = new ArrayDeque<>();
/** Queue with blocks to be validated and added to the blockchain */
private Queue<Block> blockReceivedQueue = new ConcurrentLinkedQueue<>();
/** Highest known total difficulty, representing the heaviest chain on the network */
private BigInteger highestTotalDifficulty;
@ -59,7 +59,7 @@ public class BlockQueue {
private void nudgeQueue() {
if (blockReceivedQueue.isEmpty())
return;
logger.info("BlockQueue size: {}", blockReceivedQueue.size());
while(!blockReceivedQueue.isEmpty()){
Block block = blockReceivedQueue.poll();
@ -74,10 +74,10 @@ public class BlockQueue {
* Add a list of blocks to the processing queue.
* The list is validated by making sure the first block in the received list of blocks
* is the next expected block number of the queue.
*
*
* The queue is configured to contain a maximum number of blocks to avoid memory issues
* If the list exceeds that, the rest of the received blocks in the list are discarded.
*
*
* @param blockList - the blocks received from a peer to be added to the queue
*/
public void addBlocks(List<Block> blockList) {
@ -104,13 +104,13 @@ public class BlockQueue {
blockReceivedQueue.size(),
lastBlock.getNumber());
}
/**
* Returns the last block in the queue. If the queue is empty,
* Returns the last block in the queue. If the queue is empty,
* this will return the last block added to the blockchain.
*
*
* @return The last known block this client on the network
* and will never return <code>null</code> as there is
* and will never return <code>null</code> as there is
* always the Genesis block at the start of the chain.
*/
public Block getLastBlock() {
@ -122,7 +122,7 @@ public class BlockQueue {
/**
* Reset the queue of hashes of blocks to be retrieved
* and add the best hash to the top of the queue
*
*
* @param hash - the best hash
*/
public void setBestHash(byte[] hash) {
@ -131,9 +131,9 @@ public class BlockQueue {
}
/**
* Returns the last added hash to the queue representing
* Returns the last added hash to the queue representing
* the latest known block on the network
*
*
* @return The best hash on the network known to the client
*/
public byte[] getBestHash() {
@ -158,10 +158,10 @@ public class BlockQueue {
public void addNewBlockHash(byte[] hash){
blockHashQueue.addFirst(hash);
}
/**
* Return a list of hashes from blocks that still need to be downloaded.
*
*
* @return A list of hashes for which blocks need to be retrieved.
*/
public List<byte[]> getHashes() {
@ -195,7 +195,7 @@ public class BlockQueue {
return 0;
}
}
public BigInteger getHighestTotalDifficulty() {
return highestTotalDifficulty;
}
@ -206,7 +206,7 @@ public class BlockQueue {
/**
* Returns the current number of blocks in the queue
*
*
* @return the current number of blocks in the queue
*/
public int size() {
@ -223,7 +223,7 @@ public class BlockQueue {
}
/**
* Cancel and purge the timer-thread that
* Cancel and purge the timer-thread that
* processes the blocks in the queue
*/
public void close() {

View File

@ -7,7 +7,7 @@ import org.ethereum.net.message.Message;
* been offered This class also contains the last time a message was offered and
* is updated when an answer has been received to it can be removed from the
* queue.
*
*
* @author Roman Mandeleil
*/
public class MessageRoundtrip {

View File

@ -8,7 +8,7 @@ public class Capability implements Comparable<Capability> {
public final static String P2P = "p2p";
public final static String ETH = "eth";
public final static String SHH = "shh";
private String name;
private byte version;
@ -16,7 +16,7 @@ public class Capability implements Comparable<Capability> {
this.name = name;
this.version = version;
}
public String getName() {
return name;
}
@ -24,7 +24,7 @@ public class Capability implements Comparable<Capability> {
public byte getVersion() {
return version;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
@ -41,7 +41,7 @@ public class Capability implements Comparable<Capability> {
public int compareTo(Capability o) {
return this.name.compareTo(o.name);
}
public String toString() {
return name + ":" + version;
}

View File

@ -50,12 +50,12 @@ public class PeerClient {
Bootstrap b = new Bootstrap();
b.group(workerGroup);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.option(ChannelOption.MESSAGE_SIZE_ESTIMATOR, DefaultMessageSizeEstimator.DEFAULT);
b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONFIG.peerConnectionTimeout());
b.remoteAddress(host, port);
b.handler(ethereumChannelInitializer);
// Start the client.

View File

@ -76,7 +76,7 @@ public class BlockHashesMessage extends EthMessage {
@Override
public String toString() {
if (!parsed) parse();
StringBuffer sb = Utils.getHashlistShort(this.blockHashes);
return "[" + this.getCommand().name() + sb.toString() + "] (" + this.blockHashes.size() + ")";
}

View File

@ -4,7 +4,7 @@ import org.ethereum.net.eth.EthMessageCodes;
import org.ethereum.net.message.Message;
public abstract class EthMessage extends Message {
public EthMessage() {}
public EthMessage(byte[] encoded) {

View File

@ -7,7 +7,7 @@ import java.util.Map;
* A list of commands for the Ethereum network protocol.
* <br>
* The codes for these commands are the first byte in every packet.
*
*
* @see <a href="https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol">
* https://github.com/ethereum/wiki/wiki/Ethereum-Wire-Protocol</a>
*/
@ -56,8 +56,8 @@ public enum EthMessageCodes {
/**
* [+0x07 [blockHeader, transactionList, uncleList], totalDifficulty] <br>
* Specify a single block that the peer should know about. The composite item
* in the list (following the message ID) is a block in the format described
* Specify a single block that the peer should know about. The composite item
* in the list (following the message ID) is a block in the format described
* in the main Ethereum specification. */
NEW_BLOCK(0x07),

View File

@ -9,15 +9,15 @@ import org.spongycastle.util.encoders.Hex;
/**
* Wrapper around an Ethereum GetBlockHashes message on the network
*
*
* @see org.ethereum.net.eth.EthMessageCodes#GET_BLOCK_HASHES
*/
public class GetBlockHashesMessage extends EthMessage {
/** The newest block hash from which to start sending older hashes */
private byte[] bestHash;
/** The maximum number of blocks to return.
/** The maximum number of blocks to return.
* <b>Note:</b> the peer could return fewer. */
private int maxBlocks;
@ -80,8 +80,8 @@ public class GetBlockHashesMessage extends EthMessage {
@Override
public String toString() {
if (!parsed) parse();
return "[" + this.getCommand().name() +
" bestHash=" + Hex.toHexString(bestHash) +
return "[" + this.getCommand().name() +
" bestHash=" + Hex.toHexString(bestHash) +
" maxBlocks=" + maxBlocks + "]";
}
}

View File

@ -12,7 +12,7 @@ import static org.ethereum.net.eth.EthMessageCodes.GET_BLOCKS;
/**
* Wrapper around an Ethereum GetBlocks message on the network
*
*
* @see org.ethereum.net.eth.EthMessageCodes#GET_BLOCKS
*/
public class GetBlocksMessage extends EthMessage {

View File

@ -6,12 +6,12 @@ import org.spongycastle.util.encoders.Hex;
/**
* Wrapper around an Ethereum GetTransactions message on the network
*
*
* @see org.ethereum.net.eth.EthMessageCodes#GET_TRANSACTIONS
*/
public class GetTransactionsMessage extends EthMessage {
/** GetTransactions message is always a the same single command payload */
/** GetTransactions message is always a the same single command payload */
private final static byte[] FIXED_PAYLOAD = Hex.decode("C116");
public byte[] getEncoded() {

View File

@ -7,7 +7,7 @@ import org.spongycastle.util.encoders.Hex;
/**
* Wrapper around an Ethereum Blocks message on the network
*
*
* @see org.ethereum.net.eth.EthMessageCodes#NEW_BLOCK
*/
public class NewBlockMessage extends EthMessage {
@ -48,7 +48,7 @@ public class NewBlockMessage extends EthMessage {
if (!parsed) parse();
return block;
}
public byte[] getDifficulty(){
if (!parsed) parse();
return difficulty;

View File

@ -9,8 +9,8 @@ import org.spongycastle.util.encoders.Hex;
import static org.ethereum.net.eth.EthMessageCodes.STATUS;
/**
* Wrapper around an Ethereum Status message on the network
*
* Wrapper around an Ethereum Status message on the network
*
* @see org.ethereum.net.eth.EthMessageCodes#STATUS
*/
public class StatusMessage extends EthMessage {

View File

@ -13,12 +13,12 @@ import java.util.List;
import java.util.Set;
/**
* Wrapper around an Ethereum Transactions message on the network
*
* Wrapper around an Ethereum Transactions message on the network
*
* @see org.ethereum.net.eth.EthMessageCodes#TRANSACTIONS
*/
public class TransactionsMessage extends EthMessage {
private Set<Transaction> transactions;
public TransactionsMessage(byte[] encoded) {
@ -36,7 +36,7 @@ public class TransactionsMessage extends EthMessage {
this.transactions = transactionList;
parsed = true;
}
private void parse() {
RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0);
@ -48,7 +48,7 @@ public class TransactionsMessage extends EthMessage {
}
parsed = true;
}
private void encode() {
List<byte[]> encodedElements = new ArrayList<>();
encodedElements.add(RLP.encodeByte(TRANSACTIONS.asByte()));
@ -58,7 +58,7 @@ public class TransactionsMessage extends EthMessage {
.toArray(new byte[encodedElements.size()][]);
this.encoded = RLP.encodeList(encodedElementArray);
}
@Override
public byte[] getEncoded() {
if (encoded == null) encode();
@ -80,7 +80,7 @@ public class TransactionsMessage extends EthMessage {
public Class<?> getAnswerMessage() {
return null;
}
public String toString() {
if(!parsed) parse();
StringBuffer sb = new StringBuffer();

View File

@ -2,7 +2,7 @@ package org.ethereum.net.message;
/**
* Abstract message class for all messages on the Ethereum network
*
*
* @author Roman Mandeleil
* Created on: 06/04/14 14:58
*/
@ -18,19 +18,19 @@ public abstract class Message {
this.encoded = encoded;
parsed = false;
}
/**
* Gets the RLP encoded byte array of this message
*
*
* @return RLP encoded byte array representation of this message
*/
public abstract byte[] getEncoded();
public abstract Class<?> getAnswerMessage();
/**
* Returns the message in String format
*
*
* @return A string with all attributes of the message
*/
public abstract String toString();

View File

@ -4,61 +4,61 @@ import java.util.HashMap;
import java.util.Map;
/**
* Reason is an optional integer specifying one
* of a number of reasons for disconnect
* Reason is an optional integer specifying one
* of a number of reasons for disconnect
*/
public enum ReasonCode {
/** [0x00] Disconnect request by other peer */
REQUESTED(0x00),
/** [0x01] */
TCP_ERROR(0x01),
/** [0x02] Packets can not be parsed */
BAD_PROTOCOL(0x02),
/** [0x03] This peer is too slow or delivers unreliable data */
USELESS_PEER(0x03),
/** [0x04] Already too many connections with other peers */
TOO_MANY_PEERS(0x04),
/** [0x05] Already have a running connection with this peer */
ALREADY_CONNECTED(0x05),
/** [0x06] Version of the p2p protocol is not the same as ours */
INCOMPATIBLE_PROTOCOL(0x06),
/** [0x07] Peer identifies itself with the wrong networkId */
INCOMPATIBLE_NETWORK(0x07),
/** [0x08] Peer quit voluntarily */
PEER_QUITING(0x08),
/** [0xFF] Reason not specified */
UNKNOWN(0xFF);
private int reason;
private static final Map<Integer, ReasonCode> intToTypeMap = new HashMap<>();
static {
for (ReasonCode type : ReasonCode.values()) {
intToTypeMap.put(type.reason, type);
}
}
private ReasonCode(int reason) {
this.reason = reason;
}
public static ReasonCode fromInt(int i) {
ReasonCode type = intToTypeMap.get(Integer.valueOf(i));
if (type == null)
if (type == null)
return ReasonCode.UNKNOWN;
return type;
}
public byte asByte() {
return (byte) reason;
}

View File

@ -19,14 +19,14 @@ import org.spongycastle.util.encoders.Hex;
/**
* This class contains static values of messages on the network. These message
* will always be the same and therefore don't need to be created each time.
*
*
* @author Roman Mandeleil
* Created on: 13/04/14 20:19
*/
public class StaticMessages {
public static final String PEER_ID = Hex.toHexString(HashUtil.randomPeerId());
public final static PingMessage PING_MESSAGE = new PingMessage();
public final static PongMessage PONG_MESSAGE = new PongMessage();
public final static HelloMessage HELLO_MESSAGE = generateHelloMessage();
@ -43,7 +43,7 @@ public class StaticMessages {
new Capability(Capability.SHH, ShhHandler.VERSION));
int listenPort = SystemProperties.CONFIG.listenPort();
return new HelloMessage(p2pVersion, helloAnnouncement,
return new HelloMessage(p2pVersion, helloAnnouncement,
capabilities, listenPort, PEER_ID);
}

View File

@ -4,7 +4,7 @@ import org.spongycastle.util.encoders.Hex;
/**
* Wrapper around an Ethereum GetPeers message on the network
*
*
* @see org.ethereum.net.p2p.P2pMessageCodes#GET_PEERS
*/
public class GetPeersMessage extends P2pMessage {

View File

@ -15,7 +15,7 @@ import java.util.List;
/**
* Wrapper around an Ethereum HelloMessage on the network
*
*
* @see org.ethereum.net.p2p.P2pMessageCodes#HELLO
*/
public class HelloMessage extends P2pMessage {
@ -24,7 +24,7 @@ public class HelloMessage extends P2pMessage {
private byte p2pVersion;
/** The underlying client. A user-readable string. */
private String clientId;
/** A peer-network capability code, readable ASCII and 3 letters.
/** A peer-network capability code, readable ASCII and 3 letters.
* Currently only "eth", "shh" and "bzz" are known. */
private List<Capability> capabilities;
/** The port on which the peer is listening for an incoming connection */
@ -64,10 +64,10 @@ public class HelloMessage extends P2pMessage {
RLPElement capId = ((RLPList)capabilityList.get(i)).get(0);
RLPElement capVersion = ((RLPList)capabilityList.get(i)).get(1);
String name = new String(capId.getRLPData());
byte version = capVersion.getRLPData() == null ? 0 : capVersion.getRLPData()[0];
Capability cap = new Capability(name, version);
this.capabilities.add(cap);
}

View File

@ -32,7 +32,7 @@ import org.springframework.stereotype.Component;
/**
* Process the basic protocol messages between every peer on the network.
*
*
* Peers can send/receive
* <ul>
* <li>HELLO : Announce themselves to the network</li>
@ -48,7 +48,7 @@ import org.springframework.stereotype.Component;
public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
public final static byte VERSION = 2;
private final static Logger logger = LoggerFactory.getLogger("net");
private final Timer timer = new Timer("MessageTimer");
@ -69,7 +69,7 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
this.peerDiscoveryMode = false;
}
public P2pHandler(MessageQueue msgQueue, boolean peerDiscoveryMode) {
this.msgQueue = msgQueue;
this.peerDiscoveryMode = peerDiscoveryMode;
@ -167,7 +167,7 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
ctx.close();
killTimers();
}
private void processPeers(ChannelHandlerContext ctx, PeersMessage peersMessage) {
worldManager.getPeerDiscovery().addPeers(peersMessage.getPeers());
}
@ -264,7 +264,7 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
if (capability.getName().equals(Capability.ETH)) {
EthMessageCodes.setOffset(offset);
offset += EthMessageCodes.values().length;
}
}
if (capability.getName().equals(Capability.SHH)) {
ShhMessageCodes.setOffset(offset);
@ -295,7 +295,7 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
}, 500, 25000);
*/
}
public void killTimers(){
timer.cancel();
timer.purge();

View File

@ -57,7 +57,7 @@ public class Peer {
@Override
public String toString() {
return "[ip=" + getAddress().getHostAddress() +
return "[ip=" + getAddress().getHostAddress() +
" port=" + getPort()
+ " peerId=" + getPeerId() + "]";
}

View File

@ -16,7 +16,7 @@ import org.spongycastle.util.encoders.Hex;
/**
* Wrapper around an Ethereum Peers message on the network
*
*
* @see org.ethereum.net.p2p.P2pMessageCodes#PEERS
*/
public class PeersMessage extends P2pMessage {

View File

@ -4,7 +4,7 @@ import org.spongycastle.util.encoders.Hex;
/**
* Wrapper around an Ethereum Ping message on the network
*
*
* @see org.ethereum.net.p2p.P2pMessageCodes#PING
*/
public class PingMessage extends P2pMessage {

View File

@ -5,7 +5,7 @@ import org.spongycastle.util.encoders.Hex;
/**
* Wrapper around an Ethereum Pong message on the network
*
*
* @see org.ethereum.net.p2p.P2pMessageCodes#PONG
*/
public class PongMessage extends P2pMessage {

View File

@ -72,7 +72,7 @@ public class DiscoveryChannel {
Bootstrap b = new Bootstrap();
b.group(workerGroup);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.option(ChannelOption.MESSAGE_SIZE_ESTIMATOR, DefaultMessageSizeEstimator.DEFAULT);
b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONFIG.peerConnectionTimeout());

View File

@ -25,7 +25,7 @@ public class PeerDiscovery {
private static final Logger logger = LoggerFactory.getLogger("peerdiscovery");
private final Set<PeerInfo> peers = Collections.synchronizedSet(new HashSet<PeerInfo>());
private PeerMonitorThread monitor;
private ThreadFactory threadFactory;
private ThreadPoolExecutor executorPool;
@ -77,11 +77,11 @@ public class PeerDiscovery {
public boolean isStarted() {
return started.get();
}
public Set<PeerInfo> getPeers() {
return peers;
}
/**
* Update list of known peers with new peers
* This method checks for duplicate peer id's and addresses

View File

@ -9,8 +9,8 @@ import java.util.concurrent.ThreadPoolExecutor;
/**
* A handler to log rejected threads when execution is blocked because the
* thread bounds and queue capacities are reached
*
* @author Roman Mandeleil
*
* @author Roman Mandeleil
* Created on: 22/05/2014 10:31
*/
public class RejectionLogger implements RejectedExecutionHandler {

View File

@ -11,7 +11,7 @@ import org.springframework.stereotype.Component;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author Roman Mandeleil
* @author Roman Mandeleil
* Created on: 22/05/2014 09:26
*/
@Component

View File

@ -57,7 +57,7 @@ public class PeerServer {
b.group(bossGroup, workerGroup);
b.channel(NioServerSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.option(ChannelOption.MESSAGE_SIZE_ESTIMATOR, DefaultMessageSizeEstimator.DEFAULT);
b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONFIG.peerConnectionTimeout());

View File

@ -12,7 +12,7 @@ import org.springframework.stereotype.Component;
/**
* Process the messages between peers with 'shh' capability on the network.
*
*
* Peers with 'shh' capability can send/receive:
*
*
@ -63,7 +63,7 @@ public class ShhHandler extends SimpleChannelInboundHandler<ShhMessage> {
break;
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
logger.error(cause.getCause().toString());

View File

@ -7,7 +7,7 @@ import java.util.Map;
* A list of commands for the Whisper network protocol.
* <br>
* The codes for these commands are the first byte in every packet.
*
*
* @see <a href="https://github.com/ethereum/wiki/wiki/Wire-Protocol">
* https://github.com/ethereum/wiki/wiki/Wire-Protocol</a>
*/

View File

@ -39,7 +39,7 @@ public class MessageDecoder extends ByteToMessageDecoder {
byte[] encoded = new byte[in.readInt()];
in.readBytes(encoded);
if (loggerWire.isDebugEnabled())
loggerWire.debug("Encoded: [{}]", Hex.toHexString(encoded));
@ -54,7 +54,7 @@ public class MessageDecoder extends ByteToMessageDecoder {
out.add(msg);
in.markReaderIndex();
}
private boolean isValidEthereumPacket(ByteBuf in) {
// Ethereum message is at least 8 bytes
if (in.readableBytes() < 8)

View File

@ -39,10 +39,10 @@ public class MessageEncoder extends MessageToByteEncoder<Message> {
loggerNet.info("To: \t{} \tSend: \t{}", ctx.channel().remoteAddress(), msg);
byte[] encoded = msg.getEncoded();
if (loggerWire.isDebugEnabled())
loggerWire.debug("Encoded: [{}]", Hex.toHexString(encoded));
out.capacity(encoded.length + 8);
out.writeBytes(StaticMessages.SYNC_TOKEN);
out.writeBytes(ByteUtil.calcPacketLength(encoded));

View File

@ -124,7 +124,7 @@ public class SerpentCompiler {
// encode ref for 5 bytes
for (int i = 0; i < lexaList.size(); ++i) {
String lexa = lexaList.get(i);
if (!lexa.contains("REF_")) continue;
lexaList.add(i + 1, lexa);

View File

@ -15,7 +15,7 @@ import org.iq80.leveldb.WriteBatch;
* Created on: 20/05/2014 10:44
*/
public class Cache {
private Map<ByteArrayWrapper, Node> nodes = new ConcurrentHashMap<>();
private DB db;
private boolean isDirty;
@ -26,8 +26,8 @@ public class Cache {
/**
* Put the node in the cache if RLP encoded value is longer than 32 bytes
*
* @param o the Node which could be a pair-, multi-item Node or single Value
*
* @param o the Node which could be a pair-, multi-item Node or single Value
* @return sha3 hash of RLP encoded node if length &gt; 32 otherwise return node itself
*/
public Object put(Object o) {

View File

@ -3,40 +3,40 @@ package org.ethereum.trie;
import org.ethereum.util.Value;
/**
/**
* A Node in a Merkle Patricia Tree is one of the following:
*
*
* - NULL (represented as the empty string)
* - A two-item array [ key, value ] (1 key for 2-item array)
* - A 17-item array [ v0 ... v15, vt ] (16 keys for 17-item array)
*
* The idea is that in the event that there is a long path of nodes
* each with only one element, we shortcut the descent by setting up
* a [ key, value ] node, where the key gives the hexadecimal path
* to descend, in the compact encoding described above, and the value
*
* The idea is that in the event that there is a long path of nodes
* each with only one element, we shortcut the descent by setting up
* a [ key, value ] node, where the key gives the hexadecimal path
* to descend, in the compact encoding described above, and the value
* is just the hash of the node like in the standard radix tree.
*
*
* R
* / \
* / \
* N N
* / \ / \
* L L L L
* *
* Also, we add another conceptual change: internal nodes can no longer
* have values, only leaves with no children of their own can; however,
* since to be fully generic we want the key/value store to be able to
* store keys like 'dog' and 'doge' at the same time, we simply add
* a terminator symbol (16) to the alphabet so there is never a value
* "en-route" to another value.
*
* *
* Also, we add another conceptual change: internal nodes can no longer
* have values, only leaves with no children of their own can; however,
* since to be fully generic we want the key/value store to be able to
* store keys like 'dog' and 'doge' at the same time, we simply add
* a terminator symbol (16) to the alphabet so there is never a value
* "en-route" to another value.
*
* Where a node is referenced inside a node, what is included is:
*
*
* H(rlp.encode(x)) where H(x) = sha3(x) if len(x) &gt;= 32 else x
*
* Note that when updating a trie, you will need to store the key/value pair (sha3(x), x)
*
* Note that when updating a trie, you will need to store the key/value pair (sha3(x), x)
* in a persistent lookup table when you create a node with length &gt;= 32,
* but if the node is shorter than that then you do not need to store anything
* but if the node is shorter than that then you do not need to store anything
* when length &lt; 32 for the obvious reason that the function f(x) = x is reversible.
*
* www.ethereumJ.com
@ -52,7 +52,7 @@ public class Node {
public Node(Value val) {
this(val, false);
}
public Node(Value val, boolean dirty) {
this.value = val;
this.dirty = dirty;
@ -65,11 +65,11 @@ public class Node {
public boolean isDirty() {
return dirty;
}
public void setDirty(boolean ditry) {
this.dirty = ditry;
}
public Value getValue() {
return value;
}

View File

@ -1,14 +1,14 @@
package org.ethereum.trie;
/**
* Trie interface for the main data structure in Ethereum
* Trie interface for the main data structure in Ethereum
* which is used to store both the account state and storage of each account.
*/
public interface Trie {
/**
* Gets a value from the trie for a given key
*
*
* @param key - any length byte array
* @return an rlp encoded byte array of the stored object
*/
@ -16,43 +16,43 @@ public interface Trie {
/**
* Insert or update a value in the trie for a specified key
*
*
* @param key - any length byte array
* @param value rlp encoded byte array of the object to store
*/
public void update(byte[] key, byte[] value);
/**
* Deletes a key/value from the trie for a given key
*
*
* @param key - any length byte array
*/
public void delete(byte[] key);
/**
* Returns a SHA-3 hash from the top node of the trie
*
* @return 32-byte SHA-3 hash representing the entire contents of the trie.
*
* @return 32-byte SHA-3 hash representing the entire contents of the trie.
*/
public byte[] getRootHash();
/**
* Set the top node of the trie
*
*
* @param root - 32-byte SHA-3 hash of the root node
*/
public void setRoot(byte[] root);
/**
* Commit all the changes until now
*/
public void sync();
/**
* Discard all the changes until now
*/
public void undo();
public String getTrieDump();
public boolean validate();

View File

@ -19,19 +19,19 @@ import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;
/**
* The modified Merkle Patricia tree (trie) provides a persistent data structure
* to map between arbitrary-length binary data (byte arrays). It is defined in terms of
* a mutable data structure to map between 256-bit binary fragments and arbitrary-length
* binary data, typically implemented as a database. The core of the trie, and its sole
* requirement in terms of the protocol specification is to provide a single value that
* identifies a given set of key-value pairs, which may either a 32 byte sequence or
* the empty byte sequence. It is left as an implementation consideration to store and
* maintain the structure of the trie in a manner the allows effective and efficient
* The modified Merkle Patricia tree (trie) provides a persistent data structure
* to map between arbitrary-length binary data (byte arrays). It is defined in terms of
* a mutable data structure to map between 256-bit binary fragments and arbitrary-length
* binary data, typically implemented as a database. The core of the trie, and its sole
* requirement in terms of the protocol specification is to provide a single value that
* identifies a given set of key-value pairs, which may either a 32 byte sequence or
* the empty byte sequence. It is left as an implementation consideration to store and
* maintain the structure of the trie in a manner the allows effective and efficient
* realisation of the protocol.
*
* The trie implements a caching mechanism and will use cached values if they are present.
* If a node is not present in the cache it will try to fetch it from the database and
* store the cached value.
* The trie implements a caching mechanism and will use cached values if they are present.
* If a node is not present in the cache it will try to fetch it from the database and
* store the cached value.
*
* <b>Note:</b> the data isn't persisted unless `sync` is explicitly called.
*
@ -63,7 +63,7 @@ public class TrieImpl implements Trie {
public TrieIterator getIterator() {
return new TrieIterator(this);
}
public void setCache(Cache cache) {
this.cache = cache;
}
@ -101,14 +101,14 @@ public class TrieImpl implements Trie {
@Override
public byte[] get(byte[] key) {
if (logger.isDebugEnabled())
if (logger.isDebugEnabled())
logger.debug("Retrieving key {}", Hex.toHexString(key));
byte[] k = binToNibbles(key);
Value c = new Value(this.get(this.root, k));
return (c == null)? null : c.asBytes();
}
/**
* Insert key/value pair into trie
*
@ -140,7 +140,7 @@ public class TrieImpl implements Trie {
public void delete(String key) {
this.update(key.getBytes(), "".getBytes());
}
@Override
public void delete(byte[] key) {
delete(new String(key));
@ -149,7 +149,7 @@ public class TrieImpl implements Trie {
logger.debug("New root-hash: {}", Hex.toHexString(this.getRootHash()));
}
}
@Override
public byte[] getRootHash() {
if (root == null

View File

@ -11,7 +11,7 @@ import static org.ethereum.util.CompactEncoder.unpackToNibbles;
* Created on: 20/05/2014 10:44
*/
public class TrieIterator {
private TrieImpl trie;
private String key;
private String value;
@ -73,9 +73,9 @@ public class TrieIterator {
public int purge() {
List<byte[]> shas = this.collect();
for (byte[] sha : shas) {
this.trie.getCache().delete(sha);
this.trie.getCache().delete(sha);
}
return this.values.size();
}

View File

@ -24,7 +24,7 @@ public class ByteUtil {
}
/**
* The regular {@link java.math.BigInteger#toByteArray()} method isn't quite what we often need:
* The regular {@link java.math.BigInteger#toByteArray()} method isn't quite what we often need:
* it appends a leading zero to indicate that the number is positive and may need padding.
*
* @param b the integer to format into a byte array
@ -39,23 +39,23 @@ public class ByteUtil {
int start = (biBytes.length == numBytes + 1) ? 1 : 0;
int length = Math.min(biBytes.length, numBytes);
System.arraycopy(biBytes, start, bytes, numBytes - length, length);
return bytes;
return bytes;
}
/**
* Omitting sign indication byte.
* <br><br>
* Instead of {@link org.spongycastle.util.BigIntegers#asUnsignedByteArray(BigInteger)}
* Instead of {@link org.spongycastle.util.BigIntegers#asUnsignedByteArray(BigInteger)}
* <br>we use this custom method to avoid an empty array in case of BigInteger.ZERO
*
* @param value - any big integer number. A <code>null</code>-value will return <code>null</code>
* @return A byte array without a leading zero byte if present in the signed encoding.
* @return A byte array without a leading zero byte if present in the signed encoding.
* BigInteger.ZERO will return an array with length 1 and byte-value 0.
*/
public static byte[] bigIntegerToBytes(BigInteger value) {
if (value == null)
return null;
byte[] data = value.toByteArray();
if (data.length != 1 && data[0] == 0) {
@ -66,10 +66,10 @@ public class ByteUtil {
return data;
}
/**
/**
* Returns the amount of nibbles that match each other from 0 ...
* amount will never be larger than smallest input
*
*
* @param a - first input
* @param b - second input
* @return Number of bytes that match
@ -84,22 +84,22 @@ public class ByteUtil {
}
return i;
}
/**
* Converts a long value into a byte array.
*
*
* @param val - long value to convert
* @return <code>byte[]</code> of length 8, representing the long value
*/
public static byte[] longToBytes(long val) {
return ByteBuffer.allocate(8).putLong(val).array();
}
/**
* Convert a byte-array into a hex String.<br>
* Works similar to {@link Hex#toHexString}
* Works similar to {@link Hex#toHexString}
* but allows for <code>null</code>
*
*
* @param data - byte-array to convert to a hex-string
* @return hex representation of the data.<br>
* Returns an empty String if the input is <code>null</code>
@ -109,7 +109,7 @@ public class ByteUtil {
public static String toHexString(byte[] data) {
return data == null ? "" : Hex.toHexString(data);
}
/**
* Calculate packet length
* @param msg byte[]
@ -124,14 +124,14 @@ public class ByteUtil {
(byte)((msgLen ) & 0xFF)};
return len;
}
/**
* Cast hex encoded value from byte[] to int
*
*
* Limited to Integer.MAX_VALUE: 2^32-1 (4 bytes)
*
*
* @param b array contains the values
* @return unsigned positive int value.
* @return unsigned positive int value.
*/
public static int byteArrayToInt(byte[] b) {
if (b == null || b.length == 0)
@ -153,10 +153,10 @@ public class ByteUtil {
return new BigInteger(1, b).longValue();
}
/**
* Turn nibbles to a pretty looking output string
*
*
* Example. [ 1, 2, 3, 4, 5 ] becomes '\x11\x23\x45'
*
* @param nibbles - getting byte of data [ 04 ] and turning
@ -171,7 +171,7 @@ public class ByteUtil {
}
return buffer.toString();
}
public static String oneByteToHexString(byte value) {
String retVal = Integer.toString(value & 0xFF, 16);
if (retVal.length() == 1) retVal = "0" + retVal;
@ -197,7 +197,7 @@ public class ByteUtil {
if (bytes == 0) ++bytes;
return bytes;
}
/**
* @param arg - not more that 32 bits
* @return - bytes of the value pad with complete to 32 zeroes
@ -215,7 +215,7 @@ public class ByteUtil {
else
data = arg.toString().trim().getBytes();
if (data.length > 32)
throw new RuntimeException("values can't be more than 32 byte");
@ -304,9 +304,9 @@ public class ByteUtil {
/**
* Utility function to copy a byte array into a new byte array with given size.
* If the src length is smaller than the given size, the result will be left-padded
* If the src length is smaller than the given size, the result will be left-padded
* with zeros.
*
*
* @param value - a BigInteger with a maximum value of 2^256-1
* @return Byte array of given size with a copy of the <code>src</code>
*/

View File

@ -12,29 +12,29 @@ import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
/**
/**
* Compact encoding of hex sequence with optional terminator
*
* The traditional compact way of encoding a hex string is to convert it into binary
* - that is, a string like 0f1248 would become three bytes 15, 18, 72. However,
* this approach has one slight problem: what if the length of the hex string is odd?
* In that case, there is no way to distinguish between, say, 0f1248 and f1248.
*
* Additionally, our application in the Merkle Patricia tree requires the additional feature
* that a hex string can also have a special "terminator symbol" at the end (denoted by the 'T').
* A terminator symbol can occur only once, and only at the end.
*
* An alternative way of thinking about this to not think of there being a terminator symbol,
* but instead treat bit specifying the existence of the terminator symbol as a bit specifying
*
* The traditional compact way of encoding a hex string is to convert it into binary
* - that is, a string like 0f1248 would become three bytes 15, 18, 72. However,
* this approach has one slight problem: what if the length of the hex string is odd?
* In that case, there is no way to distinguish between, say, 0f1248 and f1248.
*
* Additionally, our application in the Merkle Patricia tree requires the additional feature
* that a hex string can also have a special "terminator symbol" at the end (denoted by the 'T').
* A terminator symbol can occur only once, and only at the end.
*
* An alternative way of thinking about this to not think of there being a terminator symbol,
* but instead treat bit specifying the existence of the terminator symbol as a bit specifying
* that the given node encodes a final node, where the value is an actual value, rather than
* the hash of yet another node.
*
* To solve both of these issues, we force the first nibble of the final byte-stream to encode
* two flags, specifying oddness of length (ignoring the 'T' symbol) and terminator status;
* these are placed, respectively, into the two lowest significant bits of the first nibble.
*
* To solve both of these issues, we force the first nibble of the final byte-stream to encode
* two flags, specifying oddness of length (ignoring the 'T' symbol) and terminator status;
* these are placed, respectively, into the two lowest significant bits of the first nibble.
* In the case of an even-length hex string, we must introduce a second nibble (of value zero)
* to ensure the hex-string is even in length and thus is representable by a whole number of bytes.
*
* to ensure the hex-string is even in length and thus is representable by a whole number of bytes.
*
* Examples:
* &gt; [ 1, 2, 3, 4, 5 ]
* '\x11\x23\x45'
@ -77,7 +77,7 @@ public class CompactEncoder {
*/
public static byte[] packNibbles(byte[] nibbles) {
int terminator = 0;
if (nibbles[nibbles.length-1] == TERMINATOR) {
terminator = 1;
nibbles = copyOf(nibbles, nibbles.length-1);
@ -100,9 +100,9 @@ public class CompactEncoder {
/**
* Unpack a binary string to its nibbles equivalent
*
*
* @param str of binary data
* @return array of nibbles in byte-format
* @return array of nibbles in byte-format
*/
public static byte[] unpackToNibbles(byte[] str) {
byte[] base = binToNibbles(str);
@ -122,7 +122,7 @@ public class CompactEncoder {
* Transforms a binary array to hexadecimal format + terminator
*
* @param str byte[]
* @return array with each individual nibble adding a terminator at the end
* @return array with each individual nibble adding a terminator at the end
*/
public static byte[] binToNibbles(byte[] str) {
byte[] hexEncoded = encode(str);

View File

@ -9,23 +9,23 @@ public class DecodeResult implements Serializable {
private int pos;
private Object decoded;
public DecodeResult(int pos, Object decoded) {
this.pos = pos;
this.decoded = decoded;
}
public int getPos() {
return pos;
}
public Object getDecoded() {
return decoded;
}
public String toString() {
return asString(this.decoded);
}
private String asString(Object decoded) {
if(decoded instanceof String) {
return (String) decoded;
@ -37,7 +37,7 @@ public class DecodeResult implements Serializable {
result += asString(item);
}
return result;
}
}
throw new RuntimeException("Not a valid type. Should not occur");
}
}

View File

@ -72,7 +72,7 @@ public abstract class FastByteComparisons {
private static class LexicographicalComparerHolder {
static final String UNSAFE_COMPARER_NAME =
LexicographicalComparerHolder.class.getName() + "$UnsafeComparer";
static final Comparer<byte[]> BEST_COMPARER = getBestComparer();
/**
* Returns the Unsafe-using Comparer, or falls back to the pure-Java
@ -91,7 +91,7 @@ public abstract class FastByteComparisons {
return lexicographicalComparerJavaImpl();
}
}
private enum PureJavaComparer implements Comparer<byte[]> {
INSTANCE;
@ -116,7 +116,7 @@ public abstract class FastByteComparisons {
return length1 - length2;
}
}
@SuppressWarnings("unused") // used via reflection
private enum UnsafeComparer implements Comparer<byte[]> {
INSTANCE;

View File

@ -10,7 +10,7 @@ public class LRUMap<K,V> extends ConcurrentHashMap<K,V> {
private static final long serialVersionUID = 1L;
protected final int maxEntries;
public LRUMap(int initialEntries, int maxEntries) {
super(initialEntries, 0.8f, 3);
this.maxEntries = maxEntries;

View File

@ -19,8 +19,8 @@ import org.ethereum.util.RLPList;
import org.spongycastle.util.encoders.Hex;
/**
* Recursive Length Prefix (RLP) encoding.
*
* Recursive Length Prefix (RLP) encoding.
*
* The purpose of RLP is to encode arbitrarily nested arrays of binary data, and
* RLP is the main encoding method used to serialize objects in Ethereum. The
* only purpose of RLP is to encode structure; encoding specific atomic data
@ -30,18 +30,18 @@ import org.spongycastle.util.encoders.Hex;
* canonical forms are to either use [[k1,v1],[k2,v2]...] with keys in
* lexicographic order or to use the higher-level Patricia Tree encoding as
* Ethereum does.
*
*
* The RLP encoding function takes in an item. An item is defined as follows:
*
*
* - A string (ie. byte array) is an item - A list of items is an item
*
*
* For example, an empty string is an item, as is the string containing the word
* "cat", a list containing any number of strings, as well as more complex data
* structures like ["cat",["puppy","cow"],"horse",[[]],"pig",[""],"sheep"]. Note
* that in the context of the rest of this article, "string" will be used as a
* synonym for "a certain number of bytes of binary data"; no special encodings
* are used and no knowledge about the content of the strings is implied.
*
*
* See: https://github.com/ethereum/wiki/wiki/%5BEnglish%5D-RLP
*
* www.ethereumJ.com
@ -57,16 +57,16 @@ public class RLP {
/**
* Reason for threshold according to Vitalik Buterin:
* - 56 bytes maximizes the benefit of both options
* - if we went with 60 then we would have only had 4 slots for long strings
* - if we went with 60 then we would have only had 4 slots for long strings
* so RLP would not have been able to store objects above 4gb
* - if we went with 48 then RLP would be fine for 2^128 space, but that's way too much
* - so 56 and 2^64 space seems like the right place to put the cutoff
* - also, that's where Bitcoin's varint does the cutof
**/
private static int SIZE_THRESHOLD = 56;
/** RLP encoding rules are defined as follows: */
/*
* For a single byte whose value is in the [0x00, 0x7f] range, that byte is
* its own RLP encoding.
@ -110,12 +110,12 @@ public class RLP {
* range of the first byte is thus [0xf8, 0xff].
*/
private static int OFFSET_LONG_LIST = 0xf7;
/* ******************************************************
* DECODING *
* ******************************************************/
private static byte decodeOneByteItem(byte[] data, int index) {
// null item
if ((data[index] & 0xFF) == OFFSET_SHORT_ITEM) {
@ -183,7 +183,7 @@ public class RLP {
}
return value;
}
private static String decodeStringItem(byte[] data, int index) {
String value = null;
@ -281,7 +281,7 @@ public class RLP {
value = valueBytes;
return value;
}
private static int nextItemLength(byte[] data, int index) {
if (index >= data.length)
@ -517,7 +517,7 @@ public class RLP {
}
return length;
}
private static int calcLengthRaw(int lengthOfLength, byte[] msgData, int index) {
byte pow = (byte) (lengthOfLength - 1);
int length = 0;
@ -527,7 +527,7 @@ public class RLP {
}
return length;
}
public static byte getCommandCode(byte[] data) {
byte command = 0;
int index = getFirstListElement(data, 0);
@ -535,7 +535,7 @@ public class RLP {
command = ((int) (command & 0xFF) == OFFSET_SHORT_ITEM) ? 0 : command;
return command;
}
/**
* Parse wire byte[] message into RLP elements
*
@ -671,11 +671,11 @@ public class RLP {
throw new RuntimeException("RLP wrong encoding", e);
}
}
/**
* Reads any RLP encoded byte-array and returns all objects as byte-array or list of byte-arrays
*
* @param data RLP encoded byte-array
*
* @param data RLP encoded byte-array
* @param pos position in the array to start reading
* @return DecodeResult encapsulates the decoded items as a single Object and the final read position
*/
@ -709,7 +709,7 @@ public class RLP {
throw new RuntimeException("Only byte values between 0x00 and 0xFF are supported, but got: " + prefix);
}
}
private static DecodeResult decodeList(byte[] data, int pos, int prevPos, int len) {
List<Object> slice = new ArrayList<>();
for (int i = 0; i < len;) {
@ -723,17 +723,17 @@ public class RLP {
}
return new DecodeResult(pos, slice.toArray());
}
/* ******************************************************
* ENCODING *
* ******************************************************/
/**
* Turn Object into its RLP encoded equivalent of a byte-array
* Support for String, Integer, BigInteger and Lists of any of these types.
*
*
* @param input as object or List of objects
* @return byte[] RLP encoded
* @return byte[] RLP encoded
*/
public static byte[] encode(Object input) {
Value val = new Value(input);
@ -749,16 +749,16 @@ public class RLP {
byte[] prefix = encodeLength(output.length, OFFSET_SHORT_LIST);
return concatenate(prefix, output);
} else {
byte[] inputAsBytes = toBytes(input);
byte[] inputAsBytes = toBytes(input);
if (inputAsBytes.length == 1) {
return inputAsBytes;
} else {
byte[] firstByte = encodeLength(inputAsBytes.length, OFFSET_SHORT_ITEM);
byte[] firstByte = encodeLength(inputAsBytes.length, OFFSET_SHORT_ITEM);
return concatenate(firstByte, inputAsBytes);
}
}
}
}
/** Integer limitation goes up to 2^31-1 so length can never be bigger than MAX_ITEM_LENGTH */
public static byte[] encodeLength(int length, int offset) {
if (length < SIZE_THRESHOLD) {
@ -796,7 +796,7 @@ public class RLP {
(byte) (singleShort >> 0 & 0xFF) };
}
}
public static byte[] encodeInt(int singleInt) {
if (singleInt <= 0xFF)
return encodeByte((byte) singleInt);
@ -821,9 +821,9 @@ public class RLP {
}
public static byte[] encodeBigInteger(BigInteger srcBigInteger) {
if(srcBigInteger == BigInteger.ZERO)
if(srcBigInteger == BigInteger.ZERO)
return encodeByte((byte)0);
else
else
return encodeElement(asUnsignedByteArray(srcBigInteger));
}
@ -910,9 +910,9 @@ public class RLP {
}
return data;
}
/*
* Utility function to convert Objects into byte arrays
* Utility function to convert Objects into byte arrays
*/
private static byte[] toBytes(Object input) {
if (input instanceof byte[]) {
@ -921,10 +921,10 @@ public class RLP {
String inputString = (String) input;
return inputString.getBytes();
} else if(input instanceof Long) {
Long inputLong = (Long) input;
Long inputLong = (Long) input;
return (inputLong == 0) ? ByteUtil.EMPTY_BYTE_ARRAY : asUnsignedByteArray(BigInteger.valueOf(inputLong));
} else if(input instanceof Integer) {
Integer inputInt = (Integer) input;
Integer inputInt = (Integer) input;
return (inputInt == 0) ? ByteUtil.EMPTY_BYTE_ARRAY : asUnsignedByteArray(BigInteger.valueOf(inputInt.intValue()));
} else if(input instanceof BigInteger) {
BigInteger inputBigInt = (BigInteger) input;

View File

@ -2,18 +2,18 @@ package org.ethereum.util;
/**
* www.ethereumJ.com
* www.ethereumJ.com
* @author: Roman Mandeleil
* Created on: 21/04/14 16:26
*/
public class RLPItem implements RLPElement {
byte[] rlpData;
public RLPItem(byte[] rlpData) {
this.rlpData = rlpData;
}
public byte[] getRLPData() {
if (rlpData.length == 0)
return null;

View File

@ -26,7 +26,7 @@ public class RLPList extends ArrayList<RLPElement> implements RLPElement {
if (element instanceof RLPList) {
RLPList rlpList = (RLPList) element;
System.out.print("[");
System.out.print("[");
for (RLPElement singleElement : rlpList) {
recursivePrint(singleElement);
}

View File

@ -29,11 +29,11 @@ public class Utils {
byte[] numberBytes = Hex.decode(hexNum.substring(2));
return (new BigInteger(1, numberBytes)).toString();
}
/**
/**
* Return formatted Date String: yyyy.MM.dd HH:mm:ss
* Based on Unix's time() input in seconds
*
*
* @param timestamp seconds since start of Unix-time
* @return String formatted as - yyyy.MM.dd HH:mm:ss
*/
@ -42,7 +42,7 @@ public class Utils {
DateFormat formatter = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
return formatter.format(date);
}
public static ImageIcon getImageIcon(String resource) {
URL imageURL = ClassLoader.getSystemResource(resource);
ImageIcon image = new ImageIcon(imageURL);
@ -59,10 +59,10 @@ public class Utils {
}
return result.toString() + "·(" + "10^" + pow + ")";
}
/**
* Decodes a hex string to address bytes and checks validity
*
* Decodes a hex string to address bytes and checks validity
*
* @param hex - a hex string of the address, e.g., 6c386a4b26f73c802f34673f7248bb118f97424a
* @return - decode and validated address byte[]
*/
@ -70,12 +70,12 @@ public class Utils {
byte[] addr = null;
try { addr = Hex.decode(hex); }
catch(DecoderException addressIsNotValid) { return null; }
if(isValidAddress(addr))
return addr;
return null;
}
public static boolean isValidAddress(byte[] addr) {
return addr != null && addr.length == 20;
}

View File

@ -30,7 +30,7 @@ public class Value {
this.value = obj;
}
}
/* *****************
* Convert
* *****************/
@ -102,7 +102,7 @@ public class Value {
// If this wasn't a slice you probably shouldn't be using this function
return new Value(null);
}
/* *****************
* Utility
* *****************/
@ -114,7 +114,7 @@ public class Value {
public boolean cmp(Value o) {
return DeepEquals.deepEquals(this, o);
}
/* *****************
* Checks
* *****************/

View File

@ -50,7 +50,7 @@ public class DataWord implements Comparable<DataWord> {
else if (data.length <= 32)
System.arraycopy(data, 0, this.data, 32 - data.length, data.length);
else
throw new RuntimeException("Data word can't exit 32 bytes: " + data);
throw new RuntimeException("Data word can't exit 32 bytes: " + data);
}
public byte[] getData() {
@ -67,12 +67,12 @@ public class DataWord implements Comparable<DataWord> {
public BigInteger value() {
return new BigInteger(1, data);
}
/**
* Converts this DataWord to an int, checking for lost information.
* If this DataWord is out of the possible range for an int result
* Converts this DataWord to an int, checking for lost information.
* If this DataWord is out of the possible range for an int result
* then an ArithmeticException is thrown.
*
*
* @return this DataWord converted to an int.
* @throws ArithmeticException - if this will not fit in an int.
*/
@ -82,12 +82,12 @@ public class DataWord implements Comparable<DataWord> {
return Integer.MAX_VALUE;
return tmpValue.intValueExact();
}
/**
* Converts this DataWord to a long, checking for lost information.
* If this DataWord is out of the possible range for a long result
* Converts this DataWord to a long, checking for lost information.
* If this DataWord is out of the possible range for a long result
* then an ArithmeticException is thrown.
*
*
* @return this DataWord converted to a long.
* @throws ArithmeticException - if this will not fit in a long.
*/
@ -153,7 +153,7 @@ public class DataWord implements Comparable<DataWord> {
if (this.data[i] != 0) break;
}
}
public void bnot() {
if (this.isZero()) return;
this.data = ByteUtil.copyToArray(MAX_VALUE.subtract(this.value()));
@ -170,13 +170,13 @@ public class DataWord implements Comparable<DataWord> {
}
this.data = result;
}
// old add-method with BigInteger quick hack
public void add2(DataWord word) {
BigInteger result = value().add(word.value());
this.data = ByteUtil.copyToArray(result.and(MAX_VALUE));
}
// TODO: mul can be done in more efficient way
// TODO: with shift left shift right trick
// TODO without BigInteger quick hack
@ -212,7 +212,7 @@ public class DataWord implements Comparable<DataWord> {
// TODO: improve with no BigInteger
public void sub(DataWord word) {
BigInteger result = value().subtract(word.value());
BigInteger result = value().subtract(word.value());
this.data = ByteUtil.copyToArray(result.and(MAX_VALUE));
}
@ -244,22 +244,22 @@ public class DataWord implements Comparable<DataWord> {
BigInteger result = sValue().remainder(word.sValue());
this.data = ByteUtil.copyToArray(result.and(MAX_VALUE));
}
public void addmod(DataWord word1, DataWord word2) {
this.add(word1);
BigInteger result = this.value().mod(word2.value());
this.data = ByteUtil.copyToArray(result.and(MAX_VALUE));
}
public void mulmod(DataWord word1, DataWord word2) {
BigInteger result = value().multiply(word1.value()).mod(word2.value());
this.data = ByteUtil.copyToArray(result.and(MAX_VALUE));
}
public String toString() {
return Hex.toHexString(data);
}
public String shortHex() {
String hexValue = Hex.toHexString(getNoLeadZeroesData()).toUpperCase();
return "0x" + hexValue.replaceFirst("^0+(?!$)", "");
@ -280,7 +280,7 @@ public class DataWord implements Comparable<DataWord> {
return true;
}
@Override
public int hashCode() {
return java.util.Arrays.hashCode(data);

View File

@ -1,9 +1,9 @@
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
* 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 {

View File

@ -5,13 +5,13 @@ package org.ethereum.vm;
* This can either be a normal CALL, STATELESS call or POST call.
*/
public class MessageCall {
public enum MsgType {
CALL,
STATELESS,
public enum MsgType {
CALL,
STATELESS,
POST;
}
/** Type of internal call. Either CALL, STATELESS or POST */
private MsgType type;
@ -39,7 +39,7 @@ public class MessageCall {
this.inDataOffs = inDataOffs;
this.inDataSize = inDataSize;
}
public MessageCall(MsgType type, DataWord gas, DataWord codeAddress,
DataWord endowment, DataWord inDataOffs, DataWord inDataSize,
DataWord outDataOffs, DataWord outDataSize) {

View File

@ -5,7 +5,7 @@ import java.util.Map;
/**
* Instruction set for the Ethereum Virtual Machine
* See Yellow Paper: http://www.gavwood.com/Paper.pdf
* See Yellow Paper: http://www.gavwood.com/Paper.pdf
* - Appendix G. Virtual Machine Specification
*/
public enum OpCode {
@ -29,10 +29,10 @@ public enum OpCode {
MOD(0x06, 2),
/** (0x07) Signed modulo remainder operation*/
SMOD(0x07, 2),
/** (0x08) Addition combined with modulo
/** (0x08) Addition combined with modulo
* remainder operation */
ADDMOD(0x08, 3),
/** (0x09) Multiplication combined with modulo
/** (0x09) Multiplication combined with modulo
* remainder operation */
MULMOD(0x09, 3),
/** (0x0a) Exponential operation */
@ -72,7 +72,7 @@ public enum OpCode {
/* Environmental Information */
/** (0x30) Get address of currently
/** (0x30) Get address of currently
* executing account */
ADDRESS(0x30, 0),
/** (0x31) Get balance of the given account */
@ -81,38 +81,38 @@ public enum OpCode {
ORIGIN(0x32, 0),
/** (0x33) Get caller address */
CALLER(0x33, 0),
/** (0x34) Get deposited value by the
* instruction/transaction responsible
/** (0x34) Get deposited value by the
* instruction/transaction responsible
* for this execution */
CALLVALUE(0x34, 0),
/** (0x35) Get input data of current
/** (0x35) Get input data of current
* environment */
CALLDATALOAD(0x35, 1),
/** (0x36) Get size of input data in current
* environment */
CALLDATASIZE(0x36, 0),
/** (0x37) Copy input data in current
/** (0x37) Copy input data in current
* environment to memory */
CALLDATACOPY(0x37, 3),
/** (0x38) Get size of code running in
/** (0x38) Get size of code running in
* current environment */
CODESIZE(0x38, 0),
/** (0x39) Copy code running in current
/** (0x39) Copy code running in current
* environment to memory */
CODECOPY(0x39, 3), // [len code_start mem_start CODECOPY]
/** (0x3a) Get price of gas in current
/** (0x3a) Get price of gas in current
* environment */
GASPRICE(0x3a, 0),
/** (0x3b) Get size of code running in
/** (0x3b) Get size of code running in
* current environment with given offset */
EXTCODESIZE(0x3b, 1),
/** (0x3c) Copy code running in current
/** (0x3c) Copy code running in current
* environment to memory with given offset */
EXTCODECOPY(0x3c, 4),
/* Block Information */
/** (0x40) Get hash of most recent
/** (0x40) Get hash of most recent
* complete block */
PREVHASH(0x40, 0),
/** (0x41) Get the blocks coinbase address */
@ -142,7 +142,7 @@ public enum OpCode {
SSTORE(0x55, 2),
/** (0x56) Alter the program counter */
JUMP(0x56, 1),
/** (0x57) Conditionally alter the program
/** (0x57) Conditionally alter the program
* counter */
JUMPI(0x57, 2),
/** (0x58) Get the program counter */
@ -218,7 +218,7 @@ public enum OpCode {
PUSH30(0x7d, 0),
/** (0x7e) Place 31-byte item on stack */
PUSH31(0x7e, 0),
/** (0x7f) Place 32-byte (full word)
/** (0x7f) Place 32-byte (full word)
* item on stack */
PUSH32(0x7f, 0),
@ -316,7 +316,7 @@ public enum OpCode {
private byte opcode;
private int require;
private static final Map<Byte, OpCode> intToTypeMap = new HashMap<>();
private static final Map<String, Byte> stringToByteMap = new HashMap<>();
@ -326,19 +326,19 @@ public enum OpCode {
stringToByteMap.put(type.name(), type.opcode);
}
}
private OpCode(int op, int require) {
this.opcode = (byte) op;
this.require = require;
}
public byte val() {
return opcode;
}
/**
* Returns the mininum amount of items required on the stack for this operation
*
*
* @return minimum amount of expected items on the stack
*/
public int require() {

View File

@ -32,7 +32,7 @@ import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY;
* Created on: 01/06/2014 10:45
*/
public class Program {
private static final Logger logger = LoggerFactory.getLogger("VM");
private static final Logger gasLogger = LoggerFactory.getLogger("gas");
@ -57,10 +57,10 @@ public class Program {
ProgramInvoke invokeData;
public Program(byte[] ops, ProgramInvoke invokeData) {
if (ops == null) ops = EMPTY_BYTE_ARRAY;
this.ops = ops;
if (invokeData != null) {
this.invokeData = invokeData;
this.programAddress = invokeData.getOwnerAddress();
@ -88,7 +88,7 @@ public class Program {
public void setLastOp(byte op) {
this.lastOp = op;
}
/**
* Should be set only after the OP is fully executed
* @param op
@ -96,7 +96,7 @@ public class Program {
public void setPreviouslyExecutedOp(byte op) {
this.previouslyExecutedOp = op;
}
/**
* returns the last fully executed OP
* @return
@ -104,7 +104,7 @@ public class Program {
public byte getPreviouslyExecutedOp() {
return this.previouslyExecutedOp;
}
public void stackPush(byte[] data) {
DataWord stackWord = new DataWord(data);
stack.push(stackWord);
@ -123,7 +123,7 @@ public class Program {
public void stackPush(DataWord stackWord) {
stack.push(stackWord);
}
public Stack<DataWord> getStack() {
return this.stack;
}
@ -138,7 +138,7 @@ public class Program {
public void setPC(int pc) {
this.pc = pc;
if (this.pc >= ops.length)
stop();
}
@ -175,11 +175,11 @@ public class Program {
public DataWord stackPop() {
return stack.pop();
}
/**
* Verifies that the stack is at least <code>stackSize</code>
* @param stackSize int
* @throws StackTooSmallException If the stack is
* @throws StackTooSmallException If the stack is
* smaller than <code>stackSize</code>
*/
public void stackRequire(int stackSize) {
@ -203,7 +203,7 @@ public class Program {
/**
* Allocates a piece of memory and stores value at given offset address
*
*
* @param addr is the offset address
* @param allocSize size of memory needed to write
* @param value the data to write to memory
@ -213,11 +213,11 @@ public class Program {
allocateMemory(addr, allocSize);
System.arraycopy(value, 0, memory.array(), addr, value.length);
}
public DataWord memoryLoad(DataWord addr) {
return memoryLoad(addr.intValue());
}
public DataWord memoryLoad(int address) {
allocateMemory(address, DataWord.ZERO.getData().length);
@ -255,14 +255,14 @@ public class Program {
/**
* Allocates extra memory in the program for
* a specified size, calculated from a given offset
*
*
* @param offset the memory address offset
* @param size the number of bytes to allocate
*/
public void allocateMemory(int offset, int size) {
int memSize = memory != null ? memory.limit() : 0;
double newMemSize = Math.max(memSize, size != 0 ?
double newMemSize = Math.max(memSize, size != 0 ?
Math.ceil((double) (offset + size) / 32) * 32 : 0);
ByteBuffer tmpMem = ByteBuffer.allocate((int)newMemSize);
if (memory != null)
@ -295,7 +295,7 @@ public class Program {
byte[] senderAddress = this.getOwnerAddress().getLast20Bytes();
if (logger.isInfoEnabled())
logger.info("creating a new contract inside contract run: [{}]", Hex.toHexString(senderAddress));
// actual gas subtract
DataWord gasLimit = this.getGas();
this.spendGas(gasLimit.longValue(), "internal call");
@ -332,9 +332,9 @@ public class Program {
ProgramInvoke programInvoke = programInvokeFactory.createProgramInvoke(
this, new DataWord(newAddress), DataWord.ZERO, gasLimit,
newBalance, null, track);
ProgramResult result = null;
if (programCode != null && programCode.length != 0) {
VM vm = new VM();
Program program = new Program(programCode, programInvoke);
@ -343,8 +343,8 @@ public class Program {
this.result.addDeleteAccounts(result.getDeleteAccounts());
this.result.addLogInfos(result.getLogInfoList());
}
if (result != null &&
if (result != null &&
result.getException() != null &&
result.getException() instanceof Program.OutOfGasException) {
logger.debug("contract run halted by Exception: contract: [{}], exception: [{}]",
@ -374,7 +374,7 @@ public class Program {
// IN SUCCESS PUSH THE ADDRESS INTO THE STACK
stackPush(new DataWord(newAddress));
// 5. REFUND THE REMAIN GAS
long refundGas = gasLimit.longValue() - result.getGasUsed();
@ -390,14 +390,14 @@ public class Program {
/**
* That method is for internal code invocations
*
*
* - Normal calls invoke a specified contract which updates itself
* - Stateless calls invoke code from another contract, within the context of the caller
*
* @param msg is the message call object
*/
public void callToAddress(MessageCall msg) {
byte[] data = memoryChunk(msg.getInDataOffs(), msg.getInDataSize()).array();
// FETCH THE SAVED STORAGE
@ -420,7 +420,7 @@ public class Program {
Hex.toHexString(senderAddress), Hex.toHexString(codeAddress));
throw new OutOfGasException();
}
BigInteger endowment = msg.getEndowment().value();
BigInteger senderBalance = result.getRepository().getBalance(senderAddress);
if (senderBalance.compareTo(endowment) < 0) {
@ -429,22 +429,22 @@ public class Program {
}
result.getRepository().addBalance(senderAddress, endowment.negate());
BigInteger contextBalance = result.getRepository().addBalance(contextAddress, endowment);
if (invokeData.byTestingSuite()) {
// This keeps track of the calls created for a test
this.getResult().addCallCreate(data, contextAddress,
msg.getGas().getNoLeadZeroesData(),
msg.getGas().getNoLeadZeroesData(),
msg.getEndowment().getNoLeadZeroesData());
}
// actual gas subtract
this.spendGas(msg.getGas().longValue(), "internal call");
Repository trackRepository = result.getRepository().startTracking();
ProgramInvoke programInvoke = programInvokeFactory.createProgramInvoke(
this, new DataWord(contextAddress), msg.getEndowment(),
msg.getGas(), contextBalance, data, trackRepository);
ProgramResult result = null;
if (programCode != null && programCode.length != 0) {
@ -456,7 +456,7 @@ public class Program {
this.result.addDeleteAccounts(result.getDeleteAccounts());
this.result.addLogInfos(result.getLogInfoList());
}
if (result != null &&
result.getException() != null &&
result.getException() instanceof Program.OutOfGasException) {
@ -483,11 +483,11 @@ public class Program {
this.memorySave(offset, allocSize, buffer.array());
}
}
// 4. THE FLAG OF SUCCESS IS ONE PUSHED INTO THE STACK
trackRepository.commit();
stackPushOne();
// 5. REFUND THE REMAIN GAS
if (result != null) {
BigInteger refundGas = msg.getGas().value().subtract(BigInteger.valueOf(result.getGasUsed()));
@ -511,7 +511,7 @@ public class Program {
throw new OutOfGasException();
result.spendGas(gasValue);
}
public void spendAllGas() {
spendGas(invokeData.getGas().longValue() - result.getGasUsed(), "Spending all remaining");
}
@ -534,11 +534,11 @@ public class Program {
DataWord valWord = new DataWord(val);
result.getRepository().addStorageRow(this.programAddress.getLast20Bytes(), keyWord, valWord);
}
public byte[] getCode() {
return ops;
}
public byte[] getCodeAt(DataWord address) {
byte[] code = invokeData.getRepository().getCode(address.getLast20Bytes());
@ -637,7 +637,7 @@ public class Program {
public void setRuntimeFailure(RuntimeException e) {
result.setException(e);
}
public String memoryToString() {
StringBuilder memoryData = new StringBuilder();
StringBuilder firstLine = new StringBuilder();
@ -645,7 +645,7 @@ public class Program {
for (int i = 0; memory != null && i < memory.limit(); ++i) {
byte value = memory.get(i);
// Check if value is ASCII
// Check if value is ASCII
String character = ((byte) 0x20 <= value && value <= (byte) 0x7e) ? new String(new byte[] { value }) : "?";
firstLine.append(character).append("");
secondLine.append(ByteUtil.oneByteToHexString(value)).append(" ");
@ -820,29 +820,29 @@ public class Program {
public static String stringify(byte[] code, int index, String result) {
if(code == null || code.length == 0)
return result;
OpCode op = OpCode.code(code[index]);
byte[] continuedCode = null;
switch(op) {
case PUSH1: case PUSH2: case PUSH3: case PUSH4: case PUSH5: case PUSH6: case PUSH7: case PUSH8:
case PUSH9: case PUSH10: case PUSH11: case PUSH12: case PUSH13: case PUSH14: case PUSH15: case PUSH16:
case PUSH17: case PUSH18: case PUSH19: case PUSH20: case PUSH21: case PUSH22: case PUSH23: case PUSH24:
case PUSH25: case PUSH26: case PUSH27: case PUSH28: case PUSH29: case PUSH30: case PUSH31: case PUSH32:
result += ' ' + op.name() + ' ';
int nPush = op.val() - OpCode.PUSH1.val() + 1;
byte[] data = Arrays.copyOfRange(code, index+1, index + nPush + 1);
result += new BigInteger(1, data).toString() + ' ';
continuedCode = Arrays.copyOfRange(code, index + nPush + 1, code.length);
break;
default:
result += ' ' + op.name();
continuedCode = Arrays.copyOfRange(code, index + 1, code.length);
break;
}
}
return stringify(continuedCode, 0, result);
}
@ -856,13 +856,13 @@ public class Program {
@SuppressWarnings("serial")
public class OutOfGasException extends RuntimeException {}
@SuppressWarnings("serial")
public class IllegalOperationException extends RuntimeException {}
@SuppressWarnings("serial")
public class BadJumpDestinationException extends RuntimeException {}
@SuppressWarnings("serial")
public class StackTooSmallException extends RuntimeException {
public StackTooSmallException(String message) {

View File

@ -28,14 +28,14 @@ public class ProgramInvokeFactoryImpl implements ProgramInvokeFactory {
@Autowired
private Blockchain blockchain;
/**
/**
* This attribute defines the number of recursive calls allowed in the EVM
* Note: For the JVM to reach this level without a StackOverflow exception,
* ethereumj may need to be started with a JVM argument to increase
* ethereumj may need to be started with a JVM argument to increase
* the stack size. For example: -Xss10m
*/
private static final int MAX_DEPTH = 1024;
private static final int MAX_DEPTH = 1024;
// Invocation by the wire tx
@Override
public ProgramInvoke createProgramInvoke(Transaction tx, Block block, Repository repository) {
@ -188,7 +188,7 @@ public class ProgramInvokeFactoryImpl implements ProgramInvokeFactory {
Hex.toHexString(difficulty.getNoLeadZeroesData()),
gasLimit.longValue());
}
if (program.invokeData.getCallDeep() >= MAX_DEPTH)
throw program.new OutOfGasException();

View File

@ -21,7 +21,7 @@ public class ProgramInvokeImpl implements ProgramInvoke {
byte[] msgData;
/*** BLOCK env ***/
private DataWord prevHash, coinbase, timestamp,
private DataWord prevHash, coinbase, timestamp,
number, difficulty, gaslimit;
Map<DataWord, DataWord> storage;
@ -151,7 +151,7 @@ public class ProgramInvokeImpl implements ProgramInvoke {
return new DataWord();
if (index + size > msgData.length)
size = msgData.length - index;
byte[] data = new byte[32];
System.arraycopy(msgData, index, data, 0, size);
return new DataWord(data);

View File

@ -22,7 +22,7 @@ public class ProgramInvokeMockImpl implements ProgramInvoke {
// default for most tests. This can be overwritten by the test
private long gasLimit = 1000000;
public ProgramInvokeMockImpl(byte[] msgDataRaw) {
this();
this.msgData = msgDataRaw;
@ -31,9 +31,9 @@ public class ProgramInvokeMockImpl implements ProgramInvoke {
public ProgramInvokeMockImpl() {
this.repository = new RepositoryImpl("detailsMoc", "stateMoc");
this.repository.createAccount(ownerAddress);
this.repository.createAccount(contractAddress);
this.repository.saveCode(contractAddress,
this.repository.saveCode(contractAddress,
Hex.decode("385E60076000396000605f556014600054601e60"
+ "205463abcddcba6040545b51602001600a525451"
+ "6040016014525451606001601e52545160800160"
@ -84,7 +84,7 @@ public class ProgramInvokeMockImpl implements ProgramInvoke {
/* GAS op */
public DataWord getGas() {
return new DataWord(gasLimit);
}
@ -190,10 +190,10 @@ public class ProgramInvokeMockImpl implements ProgramInvoke {
public DataWord getGaslimit() {
return new DataWord(gasLimit);
}
public void setGasLimit(long gasLimit) {
this.gasLimit = gasLimit;
}
}
public void setOwnerAddress(byte[] ownerAddress) {
this.ownerAddress = ownerAddress;

View File

@ -26,35 +26,35 @@ import static org.ethereum.vm.OpCode.PUSH1;
/**
* The Ethereum Virtual Machine (EVM) is responsible for initialization
* and executing a transaction on a contract.
*
* It is a quasi-Turing-complete machine; the quasi qualification
* comes from the fact that the computation is intrinsically bounded
*
* It is a quasi-Turing-complete machine; the quasi qualification
* comes from the fact that the computation is intrinsically bounded
* through a parameter, gas, which limits the total amount of computation done.
*
* The EVM is a simple stack-based architecture. The word size of the machine
* (and thus size of stack item) is 256-bit. This was chosen to facilitate
* the SHA3-256 hash scheme and elliptic-curve computations. The memory model
* is a simple word-addressed byte array. The stack has an unlimited size.
* The machine also has an independent storage model; this is similar in concept
* to the memory but rather than a byte array, it is a word-addressable word array.
*
* Unlike memory, which is volatile, storage is non volatile and is
* maintained as part of the system state. All locations in both storage
* The EVM is a simple stack-based architecture. The word size of the machine
* (and thus size of stack item) is 256-bit. This was chosen to facilitate
* the SHA3-256 hash scheme and elliptic-curve computations. The memory model
* is a simple word-addressed byte array. The stack has an unlimited size.
* The machine also has an independent storage model; this is similar in concept
* to the memory but rather than a byte array, it is a word-addressable word array.
*
* Unlike memory, which is volatile, storage is non volatile and is
* maintained as part of the system state. All locations in both storage
* and memory are well-defined initially as zero.
*
* The machine does not follow the standard von Neumann architecture.
* Rather than storing program code in generally-accessible memory or storage,
* it is stored separately in a virtual ROM interactable only though
*
* The machine does not follow the standard von Neumann architecture.
* Rather than storing program code in generally-accessible memory or storage,
* it is stored separately in a virtual ROM interactable only though
* a specialised instruction.
*
* The machine can have exceptional execution for several reasons,
* including stack underflows and invalid instructions. These unambiguously
* and validly result in immediate halting of the machine with all state changes
* left intact. The one piece of exceptional execution that does not leave
* state changes intact is the out-of-gas (OOG) exception.
*
* Here, the machine halts immediately and reports the issue to
* the execution agent (either the transaction processor or, recursively,
*
* The machine can have exceptional execution for several reasons,
* including stack underflows and invalid instructions. These unambiguously
* and validly result in immediate halting of the machine with all state changes
* left intact. The one piece of exceptional execution that does not leave
* state changes intact is the out-of-gas (OOG) exception.
*
* Here, the machine halts immediately and reports the issue to
* the execution agent (either the transaction processor or, recursively,
* the spawning execution environment) and which will deal with it separately.
*
* www.ethereumJ.com
@ -62,22 +62,22 @@ import static org.ethereum.vm.OpCode.PUSH1;
* Created on: 01/06/2014 10:44
*/
public class VM {
private static final Logger logger = LoggerFactory.getLogger("VM");
private static final Logger dumpLogger = LoggerFactory.getLogger("dump");
private static BigInteger _32_ = BigInteger.valueOf(32);
private static String logString = "[{}]\t Op: [{}] Gas: [{}] Deep: [{}] Hint: [{}]";
private static BigInteger MAX_GAS = BigInteger.valueOf(Long.MAX_VALUE);
/* Keeps track of the number of steps performed in this VM */
private int vmCounter = 0;
public void step(Program program) {
if (CONFIG.vmTrace())
program.saveOpTrace();
try {
OpCode op = OpCode.code(program.getCurrentOp());
if (op == null)
@ -96,7 +96,7 @@ public class VM {
long gasCost = GasCost.STEP;
long gasBefore = program.getGas().longValue();
int stepBefore = program.getPC();
// Calculate fees and spend gas
switch (op) {
case STOP: case SUICIDE:
@ -123,7 +123,7 @@ public class VM {
case BALANCE:
gasCost = GasCost.BALANCE;
break;
// These all operate on memory and therefore potentially expand it:
case MSTORE:
newMemSize = memNeeded(stack.peek(), new DataWord(32));
@ -196,13 +196,13 @@ public class VM {
break;
}
program.spendGas(gasCost, op.name());
// Avoid overflows
if(newMemSize.compareTo(MAX_GAS) == 1)
throw program.new OutOfGasException();
// memory gas calc
long memoryUsage = (newMemSize.longValue() + 31) / 32 * 32;
long memoryUsage = (newMemSize.longValue() + 31) / 32 * 32;
if (memoryUsage > oldMemSize) {
memWords = (memoryUsage - oldMemSize) / 32;
long memGas = GasCost.MEMORY * memWords;
@ -219,7 +219,7 @@ public class VM {
// Log debugging line for VM
if(program.getNumber().intValue() == CONFIG.dumpBlock())
this.dumpLine(op, gasBefore, gasCost+callGas, memWords, program);
// Execute operation
switch (op) {
/**
@ -443,7 +443,7 @@ public class VM {
/**
* Bitwise Logic Operations
*/
case AND:{
case AND:{
DataWord word1 = program.stackPop();
DataWord word2 = program.stackPop();
@ -454,7 +454,7 @@ public class VM {
program.stackPush(word1);
program.step();
} break;
case OR: {
case OR: {
DataWord word1 = program.stackPop();
DataWord word2 = program.stackPop();
@ -465,7 +465,7 @@ public class VM {
program.stackPush(word1);
program.step();
} break;
case XOR: {
case XOR: {
DataWord word1 = program.stackPop();
DataWord word2 = program.stackPop();
@ -476,7 +476,7 @@ public class VM {
program.stackPush(word1);
program.step();
} break;
case BYTE:{
case BYTE:{
DataWord word1 = program.stackPop();
DataWord word2 = program.stackPop();
DataWord result = null;
@ -515,7 +515,7 @@ public class VM {
/**
* SHA3
*/
case SHA3:{
case SHA3:{
DataWord memOffsetData = program.stackPop();
DataWord lengthData = program.stackPop();
ByteBuffer buffer = program.memoryChunk(memOffsetData, lengthData);
@ -581,7 +581,7 @@ public class VM {
program.stackPush(callValue);
program.step();
} break;
case CALLDATALOAD:{
case CALLDATALOAD:{
DataWord dataOffs = program.stackPop();
DataWord value = program.getDataValue(dataOffs);
@ -600,11 +600,11 @@ public class VM {
program.stackPush(dataSize);
program.step();
} break;
case CALLDATACOPY:{
case CALLDATACOPY:{
DataWord memOffsetData = program.stackPop();
DataWord dataOffsetData = program.stackPop();
DataWord lengthData = program.stackPop();
byte[] msgData = program.getDataCopy(dataOffsetData, lengthData);
if (logger.isInfoEnabled())
@ -614,7 +614,7 @@ public class VM {
program.step();
} break;
case CODESIZE: case EXTCODESIZE: {
int length;
if (op == OpCode.CODESIZE)
length = program.getCode().length;
@ -629,7 +629,7 @@ public class VM {
program.stackPush(codeLength);
program.step();
} break;
} break;
case CODECOPY: case EXTCODECOPY: {
byte[] fullCode = ByteUtil.EMPTY_BYTE_ARRAY;
@ -733,19 +733,19 @@ public class VM {
program.step();
} break;
case DUP1: case DUP2: case DUP3: case DUP4:
case DUP5: case DUP6: case DUP7: case DUP8:
case DUP9: case DUP10: case DUP11: case DUP12:
case DUP5: case DUP6: case DUP7: case DUP8:
case DUP9: case DUP10: case DUP11: case DUP12:
case DUP13: case DUP14: case DUP15: case DUP16:{
int n = op.val() - OpCode.DUP1.val() + 1;
DataWord word_1 = stack.get(stack.size() - n);
program.stackPush(word_1.clone());
program.step();
} break;
case SWAP1: case SWAP2: case SWAP3: case SWAP4:
case SWAP5: case SWAP6: case SWAP7: case SWAP8:
case SWAP9: case SWAP10: case SWAP11: case SWAP12:
case SWAP5: case SWAP6: case SWAP7: case SWAP8:
case SWAP9: case SWAP10: case SWAP11: case SWAP12:
case SWAP13: case SWAP14: case SWAP15: case SWAP16:{
int n = op.val() - OpCode.SWAP1.val() + 2;
@ -838,7 +838,7 @@ public class VM {
if (nextPC != 0 && program.getOp(nextPC) != OpCode.JUMPDEST.val())
throw program.new BadJumpDestinationException();
}
if (logger.isInfoEnabled())
hint = "~> " + nextPC;
@ -848,7 +848,7 @@ public class VM {
case JUMPI:{
DataWord pos = program.stackPop();
DataWord cond = program.stackPop();
if (!cond.isZero()) {
int nextPC = pos.intValue(); // possible overflow
if(program.getPreviouslyExecutedOp() < OpCode.PUSH1.val() || program.getPreviouslyExecutedOp() > OpCode.PUSH32.val()) {
@ -866,7 +866,7 @@ public class VM {
} else {
program.step();
}
} break;
case PC:{
int pc = program.getPC();
@ -925,7 +925,7 @@ public class VM {
String.format("%-12s", op.name()),
program.getGas().value(),
program.invokeData.getCallDeep(), hint);
program.createContract(value, inOffset, inSize);
program.step();
@ -940,9 +940,9 @@ public class VM {
DataWord outDataOffs = program.stackPop();
DataWord outDataSize = program.stackPop();
if (logger.isInfoEnabled()) {
hint = "addr: " + Hex.toHexString(codeAddress.getLast20Bytes())
hint = "addr: " + Hex.toHexString(codeAddress.getLast20Bytes())
+ " gas: " + gas.shortHex()
+ " inOff: " + inDataOffs.shortHex()
+ " inSize: " + inDataSize.shortHex();
@ -951,7 +951,7 @@ public class VM {
program.getGas().value(),
program.invokeData.getCallDeep(), hint);
}
MessageCall msg = new MessageCall(
op.equals(CALL) ? MsgType.CALL : MsgType.STATELESS,
gas, codeAddress, value, inDataOffs, inDataSize,
@ -978,24 +978,24 @@ public class VM {
case SUICIDE:{
DataWord address = program.stackPop();
program.suicide(address);
if (logger.isInfoEnabled())
hint = "address: " + Hex.toHexString(program.getOwnerAddress().getLast20Bytes());
program.stop();
} break;
default:
break;
}
program.setPreviouslyExecutedOp(op.val());
if (logger.isInfoEnabled() && !op.equals(CALL)
&& !op.equals(CREATE))
logger.info(logString, stepBefore, String.format("%-12s",
op.name()), program.getGas().longValue(),
program.invokeData.getCallDeep(), hint);
vmCounter++;
} catch (RuntimeException e) {
logger.warn("VM halted: [{}]", e.toString());
@ -1022,7 +1022,7 @@ public class VM {
program.spendGas(GasCost.TX_NO_ZERO_DATA * nonZeroesVals, "DATA");
program.spendGas(GasCost.TX_ZERO_DATA * zeroVals, "DATA");
}
while(!program.isStopped())
this.step(program);
@ -1034,7 +1034,7 @@ public class VM {
/**
* Utility to calculate new total memory size needed for an operation.
* <br/> Basically just offset + size, unless size is 0, in which case the result is also 0.
*
*
* @param offset starting position of the memory
* @param size number of bytes needed
* @return offset + size, unless size is 0. In that case memNeeded is also 0.
@ -1044,12 +1044,12 @@ public class VM {
return BigInteger.ZERO;
return offset.value().add(size.value());
}
/*
* Dumping the VM state at the current operation in various styles
* - standard Not Yet Implemented
* - standard+ (owner address, program counter, operation, gas left)
* - pretty (stack, memory, storage, level, contract,
* - pretty (stack, memory, storage, level, contract,
* vmCounter, internalSteps, operation
gasBefore, gasCost, memWords)
*/
@ -1057,12 +1057,12 @@ public class VM {
if(CONFIG.dumpStyle().equals("standard+")) {
switch (op) {
case STOP: case RETURN: case SUICIDE:
ContractDetails details = program.getResult().getRepository()
.getContractDetails(program.getOwnerAddress().getLast20Bytes());
List<DataWord> storageKeys = new ArrayList<>(details.getStorage().keySet());
Collections.sort((List<DataWord>) storageKeys);
for (DataWord key : storageKeys) {
dumpLogger.trace("{} {}",
Hex.toHexString(key.getNoLeadZeroesData()),
@ -1086,25 +1086,25 @@ public class VM {
String memoryString = program.memoryToString();
if(!"".equals(memoryString))
dumpLogger.trace("{}", memoryString);
dumpLogger.trace(" STORAGE");
ContractDetails details = program.getResult().getRepository()
.getContractDetails(program.getOwnerAddress().getLast20Bytes());
List<DataWord> storageKeys = new ArrayList<>(details.getStorage().keySet());
Collections.sort((List<DataWord>) storageKeys);
for (DataWord key : storageKeys) {
dumpLogger.trace("{}: {}",
key.shortHex(),
details.getStorage().get(key).shortHex());
}
int level = program.invokeData.getCallDeep();
String contract = Hex.toHexString(program.getOwnerAddress().getLast20Bytes());
String internalSteps = String.format("%4s", Integer.toHexString(program.getPC())).replace(' ', '0').toUpperCase();
dumpLogger.trace("{} | {} | #{} | {} : {} | {} | -{} | {}x32",
level, contract, vmCounter, internalSteps, op,
gasBefore, gasCost, memWords);
gasBefore, gasCost, memWords);
}
}
}
}

View File

@ -42,7 +42,7 @@ peer.connection.timeout = 2
transaction.approve.timeout = 15
# the parameter specifies how much
# time we will wait for a message
# time we will wait for a message
# to come before closing the channel
peer.channel.read.timeout = 30
@ -52,8 +52,8 @@ peer.channel.read.timeout = 30
samples.dir = samples
# everytime the application starts
# the existing database will be
# destroyed and all the data will be
# the existing database will be
# destroyed and all the data will be
# downloaded from peers again
database.reset = true

View File

@ -77,7 +77,7 @@ public class BlockTest {
+ "9e262996493846a590c7011697dba07bb7680a256ede4034212b7a1ae6c7caea73190cb0"
+ "7dedb91a07b72f34074e76a00cd22d78d556175604407dc6109797f5c8d990d05f1b352e"
+ "10c71b3dd74bc70f8201f4c0";
String block_32 = "f8f8f8f4a00a312c2b0a8f125c60a3976b6e508e740e095eb59943988d9bbfb8"
+ "aa43922e31a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4"
+ "934794e559de5527492bcb42ec68d07df0742a98ec3f1ea050188ab86bdf164ac90eb283"
@ -104,7 +104,7 @@ public class BlockTest {
assertEquals(Hex.toHexString(genesis.getParentHash()), Hex.toHexString(genesisFromRLP.getParentHash()));
assertEquals(Hex.toHexString(genesis.getStateRoot()), Hex.toHexString(genesisFromRLP.getStateRoot()));
}
@Test
public void testGenesisFromNew() {
Block genesis = Genesis.getInstance();
@ -115,7 +115,7 @@ public class BlockTest {
assertEquals(PoC7_GENESIS_HEX_HASH, Hex.toHexString(genesis.getHash()));
assertEquals(PoC7_GENESIS_HEX_RLP_ENCODED, Hex.toHexString(genesis.getEncoded()));
}
@Test /* block without transactions - block#32 in PoC5 cpp-chain */
public void testEmptyBlock() {
byte[] payload = Hex.decode(block_32);
@ -137,7 +137,7 @@ public class BlockTest {
Block block = new Block(payload);
logger.info(block.toString());
}
@Test
public void testCalcDifficulty() {
@ -157,7 +157,7 @@ public class BlockTest {
logger.info("Block#1 calculated difficulty: [{}] ", calcDifficulty.toString());
assertEquals(actualDifficulty, calcDifficulty);
}
@Test
public void testCalcGasLimit() {
BlockchainImpl blockchain = (BlockchainImpl)worldManager.getBlockchain();
@ -240,14 +240,14 @@ public class BlockTest {
// TODO
fail("Not yet implemented");
}
@Test
@Ignore
public void testUncleInvalidGenerationGap() {
// TODO
fail("Not yet implemented");
}
@Test
@Ignore
public void testUncleInvalidParentGenerationGap() {

View File

@ -19,30 +19,30 @@ public class MinerTest {
// Example block#32 from Poc5 chain - rlpEncoded without nonce
private String rlpWithoutNonce = "f894f890a00a312c2b0a8f125c60a3976b6e508e740e095eb59943988d9bbfb8"
+ "aa43922e31a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794e559de5527492bcb42ec68d07df0742a98ec3f1ea050188ab86bdf164ac90eb2835a04a8930aae5393c3a2ef1166fb95028f9456b880833ee248208609184e72a000830eca0080845387fd2080c0c0";
@Test
@Ignore
public void testMine() {
boolean miningTestEnabled = false;
if(miningTestEnabled) {
Block block = createBlock(null);
assertEquals(rlpWithoutNonce, Hex.toHexString(block.getEncodedWithoutNonce()));
System.out.println("Searching for nonce of following block: \n" + block.toString());
Miner miner = new Miner();
boolean mined = miner.mine(block, block.getDifficulty());
assertTrue(mined);
boolean valid = block.validateNonce();
assertTrue(valid);
// expectedHash is the actual hash from block#32 in PoC5 chain based on nonce below
String expectedHash = "ce7201f6cc5eb1a6f35c7dda8acda111647a0f8a5bf0518e46579b03e29fe14b";
assertEquals(expectedHash, Hex.toHexString(block.getHash()));
// expectedNonce is the actual nonce from block#32 in Poc5 chain
String expectedNonce = "0000000000000000000000000000000000000000000000001f52ebb192c4ea97"; // from Poc5 chain
// Actual is "000000000000000000000000000000000000000000000000000000000098cc15"
// Actual is "000000000000000000000000000000000000000000000000000000000098cc15"
// but that might also be a valid nonce in compliance with PoW(H!n, n) < (2^256 / difficulty)
assertEquals(expectedNonce, Hex.toHexString(block.getNonce()));
}

View File

@ -70,7 +70,7 @@ public class StateTest {
byte[] minerAddress = Hex.decode("4c5f4d519dff3c16f0d54b6866e256fbbbc1a600");
AccountState account_3 = new AccountState(BigInteger.ZERO, new BigInteger("1506260000000000000"));
trie.update(minerAddress, account_3.getEncoded());
assertEquals(expected, Hex.toHexString(trie.getRootHash()));
@ -116,7 +116,7 @@ public class StateTest {
Trie trie = new TrieImpl(new MockDB());
for (String address : Genesis.getPremine()) {
AccountState acct = new AccountState(BigInteger.ZERO, BigInteger.valueOf(2).pow(200));
trie.update(Hex.decode(address), acct.getEncoded());
trie.update(Hex.decode(address), acct.getEncoded());
}
return trie;
}

View File

@ -109,7 +109,7 @@ public class TransactionTest {
ECKey ecKey = ECKey.fromPrivate(HashUtil.sha3("cat".getBytes()));
byte[] senderPrivKey = HashUtil.sha3("cow".getBytes());
byte[] nonce = { 0x01 };
byte[] gasPrice = Hex.decode("09184e72a000");
byte[] gasLimit = Hex.decode("4255");
@ -152,14 +152,14 @@ public class TransactionTest {
byte[] testValue = BigIntegers.asUnsignedByteArray(BigInteger.valueOf(10000000000000000L));
byte[] testData = Hex.decode("");
byte[] testInit = Hex.decode("");
@Test
public void testTransactionFromSignedRLP() throws Exception {
Transaction txSigned = new Transaction(Hex.decode(RLP_ENCODED_SIGNED_TX));
assertEquals(HASH_TX, Hex.toHexString(txSigned.getHash()));
assertEquals(RLP_ENCODED_SIGNED_TX, Hex.toHexString(txSigned.getEncoded()));
assertEquals(BigInteger.ZERO, new BigInteger(1, txSigned.getNonce()));
assertEquals(new BigInteger(1, testGasPrice), new BigInteger(1, txSigned.getGasPrice()));
assertEquals(new BigInteger(1, testGasLimit), new BigInteger(1, txSigned.getGasLimit()));
@ -170,16 +170,16 @@ public class TransactionTest {
assertEquals("eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4", Hex.toHexString(BigIntegers.asUnsignedByteArray(txSigned.getSignature().r)));
assertEquals("14a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1", Hex.toHexString(BigIntegers.asUnsignedByteArray(txSigned.getSignature().s)));
}
@Test
public void testTransactionFromUnsignedRLP() throws Exception {
Transaction txUnsigned = new Transaction(Hex.decode(RLP_ENCODED_UNSIGNED_TX));
assertEquals(HASH_TX, Hex.toHexString(txUnsigned.getHash()));
assertEquals(RLP_ENCODED_UNSIGNED_TX, Hex.toHexString(txUnsigned.getEncoded()));
txUnsigned.sign(Hex.decode(KEY));
assertEquals(RLP_ENCODED_SIGNED_TX, Hex.toHexString(txUnsigned.getEncoded()));
assertEquals(RLP_ENCODED_SIGNED_TX, Hex.toHexString(txUnsigned.getEncoded()));
assertEquals(BigInteger.ZERO, new BigInteger(1, txUnsigned.getNonce()));
assertEquals(new BigInteger(1, testGasPrice), new BigInteger(1, txUnsigned.getGasPrice()));
assertEquals(new BigInteger(1, testGasLimit), new BigInteger(1, txUnsigned.getGasLimit()));
@ -190,11 +190,11 @@ public class TransactionTest {
assertEquals("eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4", Hex.toHexString(BigIntegers.asUnsignedByteArray(txUnsigned.getSignature().r)));
assertEquals("14a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1", Hex.toHexString(BigIntegers.asUnsignedByteArray(txUnsigned.getSignature().s)));
}
@Test
public void testTransactionFromNew1() throws MissingPrivateKeyException {
Transaction txNew = new Transaction(testNonce, testGasPrice, testGasLimit, testReceiveAddress, testValue, testData);
assertEquals("", Hex.toHexString(txNew.getNonce()));
assertEquals(new BigInteger(1, testGasPrice), new BigInteger(1, txNew.getGasPrice()));
assertEquals(new BigInteger(1, testGasLimit), new BigInteger(1, txNew.getGasLimit()));
@ -202,35 +202,35 @@ public class TransactionTest {
assertEquals(new BigInteger(1, testValue), new BigInteger(1, txNew.getValue()));
assertEquals("", Hex.toHexString(txNew.getData()));
assertNull(txNew.getSignature());
assertEquals(RLP_ENCODED_RAW_TX, Hex.toHexString(txNew.getEncodedRaw()));
assertEquals(HASH_TX, Hex.toHexString(txNew.getHash()));
assertEquals(RLP_ENCODED_UNSIGNED_TX, Hex.toHexString(txNew.getEncoded()));
txNew.sign(Hex.decode(KEY));
assertEquals(RLP_ENCODED_SIGNED_TX, Hex.toHexString(txNew.getEncoded()));
assertEquals(RLP_ENCODED_SIGNED_TX, Hex.toHexString(txNew.getEncoded()));
assertEquals(27, txNew.getSignature().v);
assertEquals("eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4", Hex.toHexString(BigIntegers.asUnsignedByteArray(txNew.getSignature().r)));
assertEquals("14a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1", Hex.toHexString(BigIntegers.asUnsignedByteArray(txNew.getSignature().s)));
}
@Test
public void testTransactionFromNew2() throws MissingPrivateKeyException {
byte[] privKeyBytes = Hex.decode("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4");
String RLP_TX_UNSIGNED = "eb8085e8d4a510008227109413978aee95f38490e9769c39b2773ed763d9cd5f872386f26fc1000080808080";
String RLP_TX_SIGNED = "f86b8085e8d4a510008227109413978aee95f38490e9769c39b2773ed763d9cd5f872386f26fc10000801ba0eab47c1a49bf2fe5d40e01d313900e19ca485867d462fe06e139e3a536c6d4f4a014a569d327dcda4b29f74f93c0e9729d2f49ad726e703f9cd90dbb0fbf6649f1";
String HASH_TX_UNSIGNED = "328ea6d24659dec48adea1aced9a136e5ebdf40258db30d1b1d97ed2b74be34e";
byte[] nonce = BigIntegers.asUnsignedByteArray(BigInteger.ZERO);
byte[] gasPrice = Hex.decode("e8d4a51000"); // 1000000000000
byte[] gas = Hex.decode("2710"); // 10000
byte[] recieveAddress = Hex.decode("13978aee95f38490e9769c39b2773ed763d9cd5f");
byte[] value = Hex.decode("2386f26fc10000"); //10000000000000000"
byte[] data = new byte[0];
Transaction tx = new Transaction(nonce, gasPrice, gas, recieveAddress, value, data);
// Testing unsigned
String encodedUnsigned = Hex.toHexString(tx.getEncoded());
assertEquals(RLP_TX_UNSIGNED, encodedUnsigned);
@ -238,7 +238,7 @@ public class TransactionTest {
// Testing signed
tx.sign(privKeyBytes);
String encodedSigned = Hex.toHexString(tx.getEncoded());
String encodedSigned = Hex.toHexString(tx.getEncoded());
assertEquals(RLP_TX_SIGNED, encodedSigned);
assertEquals(HASH_TX_UNSIGNED, Hex.toHexString(tx.getHash()));
}

View File

@ -28,19 +28,19 @@ import com.google.common.util.concurrent.MoreExecutors;
public class ECKeyTest {
private static final Logger log = LoggerFactory.getLogger(ECKeyTest.class);
private String privString = "3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4";
private BigInteger privateKey = new BigInteger(Hex.decode(privString));
private String pubString = "0497466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce78549b514e4453d74ef11b0cd5e4e4c364effddac8b51bcfc8de80682f952896f";
private String compressedPubString = "0397466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce7";
private byte[] pubKey = Hex.decode(pubString);
private byte[] compressedPubKey = Hex.decode(compressedPubString);
private String address = "8a40bfaa73256b60764c1bf40675a99083efb075";
private String exampleMessage = new String("This is an example of a signed message.");
private String sigBase64 = "HD5AsBr4wuH6UU9tXuSJhUvgfGayfwoY0cKT03sFUjnpQsupHznd/3mCIRfLuNHlRCVGdAyHecdyM8IVZMtc1I8=";
@Test
public void testHashCode() {
Assert.assertEquals(1866897155, ECKey.fromPrivate(privateKey).hashCode());
@ -84,7 +84,7 @@ public class ECKeyTest {
byte[] pubFromPriv = ECKey.publicKeyFromPrivate(privateKey, false);
assertArrayEquals(pubKey, pubFromPriv);
}
@Test
public void testPublicKeyFromPrivateCompressed() {
byte[] pubFromPriv = ECKey.publicKeyFromPrivate(privateKey, true);
@ -105,7 +105,7 @@ public class ECKeyTest {
@Test
public void testEthereumSign() throws IOException {
// TODO: Understand why key must be decompressed for this to work
// TODO: Understand why key must be decompressed for this to work
ECKey key = ECKey.fromPrivate(privateKey).decompress();
System.out.println("Secret\t: " + Hex.toHexString(key.getPrivKeyBytes()));
System.out.println("Pubkey\t: " + Hex.toHexString(key.getPubKey()));
@ -116,7 +116,7 @@ public class ECKeyTest {
System.out.println("Signtr\t: " + output + " (Base64, length: " + output.length() + ")");
assertEquals(sigBase64, output);
}
@Test
public void testVerifySignature1() {
ECKey key = ECKey.fromPublicOnly(pubKey);
@ -125,7 +125,7 @@ public class ECKeyTest {
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray(), (byte) 28);
key.verify(HashUtil.sha3(exampleMessage.getBytes()), sig);
}
@Test
public void testVerifySignature2() {
BigInteger r = new BigInteger("c52c114d4f5a3ba904a9b3036e5e118fe0dbb987fe3955da20f2cd8f6c21ab9c", 16);
@ -158,7 +158,7 @@ public class ECKeyTest {
// todo: add test assertion when the sign/verify part actually works.
}
@Test
public void testSValue() throws Exception {
// Check that we never generate an S value that is larger than half the curve order. This avoids a malleability
@ -184,7 +184,7 @@ public class ECKeyTest {
assertEquals(sigs.get(0), duplicate);
assertEquals(sigs.get(0).hashCode(), duplicate.hashCode());
}
@Test
public void testSignVerify() {
ECKey key = ECKey.fromPrivate(privateKey);
@ -192,7 +192,7 @@ public class ECKeyTest {
ECDSASignature output = key.doSign(message.getBytes());
assertTrue(key.verify(message.getBytes(), output));
}
@Test
public void testIsPubKeyCanonicalCorect() {
// Test correct prefix 4, right length 65
@ -205,7 +205,7 @@ public class ECKeyTest {
byte[] canonicalPubkey3 = new byte[33]; canonicalPubkey3[0] = 0x03;
assertTrue(ECKey.isPubKeyCanonical(canonicalPubkey3));
}
@Test
public void testIsPubKeyCanonicalWrongLength() {
// Test correct prefix 4, but wrong length !65
@ -218,7 +218,7 @@ public class ECKeyTest {
byte[] nonCanonicalPubkey3 = new byte[32]; nonCanonicalPubkey3[0] = 0x03;
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey3));
}
@Test
public void testIsPubKeyCanonicalWrongPrefix() {
// Test wrong prefix 4, right length 65
@ -231,7 +231,7 @@ public class ECKeyTest {
byte[] nonCanonicalPubkey6 = new byte[33];
assertFalse(ECKey.isPubKeyCanonical(nonCanonicalPubkey6));
}
@Test
public void keyRecovery() throws Exception {
ECKey key = new ECKey();
@ -250,7 +250,7 @@ public class ECKeyTest {
}
assertTrue(found);
}
@Test
public void testSignedMessageToKey() throws SignatureException {
byte[] messageHash = HashUtil.sha3(exampleMessage.getBytes());
@ -258,7 +258,7 @@ public class ECKeyTest {
assertNotNull(key);
assertArrayEquals(pubKey, key.getPubKey());
}
@Test
public void testGetPrivKeyBytes() {
ECKey key = new ECKey();
@ -271,9 +271,9 @@ public class ECKeyTest {
ECKey key0 = new ECKey();
ECKey key1 = ECKey.fromPrivate(privateKey);
ECKey key2 = ECKey.fromPrivate(privateKey);
assertFalse(key0.equals(key1));
assertTrue(key1.equals(key1));
assertTrue(key1.equals(key2));
}
}
}

View File

@ -19,10 +19,10 @@ public class ByteArrayWrapperTest {
static ByteArrayWrapper wrapper2;
static ByteArrayWrapper wrapper3;
static ByteArrayWrapper wrapper4;
@BeforeClass
public static void loadByteArrays() {
String block = "f9072df8d3a077ef4fdaf389dca53236bcf7f72698e154eab2828f86fbc4fc6c"
+ "d9225d285c89a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0"
+ "a142fd40d493479476f5eabe4b342ee56b8ceba6ab2a770c3e2198e7a0faa0ca"
@ -81,18 +81,18 @@ public class ByteArrayWrapperTest {
+ "2ba37af8e83c3741225da066ae0ec1217b0ca698a5369d4881e1c4cbde56af99"
+ "31ebf9281580a23b659c08a051f947cb2315d0259f55848c630caa10cd91d6e4"
+ "4ff8bad7758c65b25e2191308227d2c0";
byte[] test1 = Hex.decode(block);
byte[] test2 = Hex.decode(block);
byte[] test3 = Hex.decode("4ff8bad7758c65b25e2191308227d2c0");
byte[] test4 = Hex.decode("");
wrapper1 = new ByteArrayWrapper(test1);
wrapper2 = new ByteArrayWrapper(test2);
wrapper3 = new ByteArrayWrapper(test3);
wrapper4 = new ByteArrayWrapper(test4);
}
@Test
public void testEqualsObject() {
assertTrue(wrapper1.equals(wrapper2));
@ -109,11 +109,11 @@ public class ByteArrayWrapperTest {
assertTrue(wrapper1.compareTo(wrapper4) > 1);
assertTrue(wrapper2.compareTo(wrapper3) > 1);
}
@Test
public void testEqualsPerformance() {
boolean testEnabled = false;
if(testEnabled) {
final int ITERATIONS = 10000000;
long start1 = System.currentTimeMillis();
@ -125,18 +125,18 @@ public class ByteArrayWrapperTest {
wrapper2.getData());
}
System.out.println(System.currentTimeMillis() - start1 + "ms");
long start2 = System.currentTimeMillis();
for (int i = 0; i < ITERATIONS; i++) {
Arrays.equals(wrapper1.getData(), wrapper2.getData());
}
System.out.println(System.currentTimeMillis() - start2 + "ms");
long start3 = System.currentTimeMillis();
for (int i = 0; i < ITERATIONS; i++) {
FastByteComparisons.compareTo(wrapper1.getData(), 0, wrapper1.getData().length, wrapper2.getData(), 0, wrapper1.getData().length);
}
System.out.println(System.currentTimeMillis() - start3 + "ms");
}
}
}
}

View File

@ -22,7 +22,7 @@ import org.spongycastle.util.encoders.Hex;
* Created on: 11/06/2014 14:54
*/
public class TrackDatabaseTest {
@Test
public void test1() {
@ -50,7 +50,7 @@ public class TrackDatabaseTest {
db1.close();
}
@AfterClass
public static void destroyDB() {
try {

View File

@ -18,9 +18,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Test file specific for tests maintained in the GitHub repository
* Test file specific for tests maintained in the GitHub repository
* by the Ethereum DEV team. <br/>
*
*
* @see <a href="https://github.com/ethereum/tests/">https://github.com/ethereum/tests/</a>
*/
@RunWith(Suite.class)
@ -31,7 +31,7 @@ public class GitHubJSONTestSuite {
private static Logger logger = LoggerFactory.getLogger("TCK-Test");
protected static void runGitHubJsonTest(String json) throws ParseException {
Assume.assumeFalse("Online test is not available", json.equals(""));
@ -44,7 +44,7 @@ public class GitHubJSONTestSuite {
while (testIterator.hasNext()){
TestCase testCase = testIterator.next();
TestRunner runner = new TestRunner();
List<String> result = runner.runTestCase(testCase);
Assert.assertTrue(result.isEmpty());

View File

@ -97,6 +97,6 @@ public class GitHubStateTest {
}

View File

@ -16,56 +16,56 @@ public class GitHubVMTest {
String json = JSONReader.loadJSON("VMTests/vmArithmeticTest.json");
GitHubJSONTestSuite.runGitHubJsonTest(json);
}
@Test // testing full suite
public void testBitwiseLogicOperationFromGitHub() throws ParseException {
String json = JSONReader.loadJSON("VMTests/vmBitwiseLogicOperationTest.json");
GitHubJSONTestSuite.runGitHubJsonTest(json);
}
@Test // testing full suite
public void testBlockInfoFromGitHub() throws ParseException {
String json = JSONReader.loadJSON("VMTests/vmBlockInfoTest.json");
GitHubJSONTestSuite.runGitHubJsonTest(json);
}
@Test // testing full suite
public void testEnvironmentalInfoFromGitHub() throws ParseException {
String json = JSONReader.loadJSON("VMTests/vmEnvironmentalInfoTest.json");
GitHubJSONTestSuite.runGitHubJsonTest(json);
}
@Test // testing full suite
public void testIOandFlowOperationsFromGitHub() throws ParseException {
String json = JSONReader.loadJSON("VMTests/vmIOandFlowOperationsTest.json");
GitHubJSONTestSuite.runGitHubJsonTest(json);
}
@Test // testing full suite
public void testPushDupSwapFromGitHub() throws ParseException {
String json = JSONReader.loadJSON("VMTests/vmPushDupSwapTest.json");
GitHubJSONTestSuite.runGitHubJsonTest(json);
}
@Test // testing full suite
public void testShaFromGitHub() throws ParseException {
String json = JSONReader.loadJSON("VMTests/vmSha3Test.json");
GitHubJSONTestSuite.runGitHubJsonTest(json);
}
@Test // testing full suite
public void testVMGitHub() throws ParseException {
String json = JSONReader.loadJSON("VMTests/vmtests.json");
GitHubJSONTestSuite.runGitHubJsonTest(json);
}
@Test // testing full suite
public void testVMLogGitHub() throws ParseException {

View File

@ -13,7 +13,7 @@ import java.util.ArrayList;
import java.util.List;
/**
* @author Roman Mandeleil
* @author Roman Mandeleil
* Created on: 22/05/2014 09:26
*/
public class MinerThread implements Runnable {

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More