mirror of
https://github.com/status-im/ethereumj-personal.git
synced 2025-02-26 18:50:28 +00:00
Apply basic formatting
- Do not align assignments on equals signs - Use spaces before opening curly braces - Add spaces between parameters as necessary - Insert newlines between method declarations - Other minor changes This formatting pass is not comprehensive. For the most part, it does not deal with Javadoc formatting, line wrapping, parameter alignment rules or a number of other items that can be addressed later.
This commit is contained in:
parent
e5fcf5b48e
commit
58874cfc7e
@ -1,4 +1,3 @@
|
||||
|
||||
<!--
|
||||
|
||||
Publish from local ${user.home}/.m2/repository
|
||||
@ -25,16 +24,15 @@
|
||||
-->
|
||||
|
||||
|
||||
|
||||
<project name="ethereumj-bintray" default="publish" basedir="." >
|
||||
<project name="ethereumj-bintray" default="publish" basedir=".">
|
||||
|
||||
<tstamp/>
|
||||
|
||||
<property name="artifact.groupId" value="org.ethereum"/>
|
||||
<property name="artifact.id" value="ethereumj"/>
|
||||
<property name="artifact.version" value="0.7.14"/>
|
||||
<property name="artifact.path" value="" />
|
||||
<property name="artifact.snapshot" value="snapshot" />
|
||||
<property name="artifact.path" value=""/>
|
||||
<property name="artifact.snapshot" value="snapshot"/>
|
||||
|
||||
<property name="repo.location" value="${user.home}/.m2/repository"/>
|
||||
<property name="artifact.group.path" value="${artifact.groupId}"/>
|
||||
@ -54,13 +52,13 @@
|
||||
else="${artifact.version}">
|
||||
|
||||
|
||||
<isset property="artifact.snapshot" />
|
||||
<isset property="artifact.snapshot"/>
|
||||
</condition>
|
||||
|
||||
|
||||
<property name="bintray.publish" value="1"/>
|
||||
|
||||
<property name="bintray.file.path" value="${artifact.groupId}/${artifact.id}/${bintray.version}" />
|
||||
<property name="bintray.file.path" value="${artifact.groupId}/${artifact.id}/${bintray.version}"/>
|
||||
|
||||
<property name="encoded.bintray.file.path" value=""/>
|
||||
|
||||
@ -78,8 +76,6 @@
|
||||
</taskdef>
|
||||
|
||||
|
||||
|
||||
|
||||
<target name="definePath">
|
||||
<!--[groupId('.'->'/')]\[artifactId]\[version]-->
|
||||
<!--[artifactId]-[version][suffix]-->
|
||||
@ -93,11 +89,11 @@
|
||||
|
||||
<var name="artifact.full.path" unset="true"/>
|
||||
<property name="artifact.full.path"
|
||||
value="${repo.location}/${artifact.group.path}/${artifact.id}/${artifact.version}/" />
|
||||
value="${repo.location}/${artifact.group.path}/${artifact.id}/${artifact.version}/"/>
|
||||
|
||||
<var name="bintray.file.path" unset="true"/>
|
||||
<property name="bintray.file.path"
|
||||
value="${artifact.group.path}/${artifact.id}/${bintray.version}/${artifact.id}-${bintray.version}" />
|
||||
value="${artifact.group.path}/${artifact.id}/${bintray.version}/${artifact.id}-${bintray.version}"/>
|
||||
|
||||
<echo message="${bintray.file.path}"/>
|
||||
|
||||
@ -116,7 +112,6 @@
|
||||
</target>
|
||||
|
||||
|
||||
|
||||
<target name="publish" depends="dependency, definePath">
|
||||
|
||||
<parallel>
|
||||
@ -169,6 +164,4 @@
|
||||
</target>
|
||||
|
||||
|
||||
|
||||
|
||||
</project>
|
||||
|
@ -8,14 +8,14 @@
|
||||
<name>EthereumJ</name>
|
||||
<url>http://www.ethereumj.org</url>
|
||||
|
||||
<!--
|
||||
<!--
|
||||
* Install jar with sources to the local maven repository
|
||||
mvn install -Dmaven.test.skip=true
|
||||
|
||||
* To generate source for ANTLR parser/lexer
|
||||
mvn antlr4:antlr4
|
||||
|
||||
-->
|
||||
-->
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
@ -347,7 +347,7 @@
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!--
|
||||
<!--
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.3</version>
|
||||
@ -367,8 +367,7 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
-->
|
||||
|
||||
-->
|
||||
|
||||
<plugin>
|
||||
<groupId>org.antlr</groupId>
|
||||
@ -400,7 +399,6 @@
|
||||
</plugin>
|
||||
|
||||
|
||||
|
||||
</plugins>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
|
@ -14,7 +14,7 @@ import org.ethereum.facade.EthereumFactory;
|
||||
|
||||
public class Start {
|
||||
|
||||
public static void main(String args[]){
|
||||
public static void main(String args[]) {
|
||||
CLIInterface.call(args);
|
||||
Ethereum ethereum = EthereumFactory.createEthereum();
|
||||
|
||||
|
@ -19,35 +19,35 @@ public class CLIInterface {
|
||||
private static final Logger logger = LoggerFactory.getLogger("cli");
|
||||
|
||||
|
||||
public static void call(String[] args){
|
||||
public static void call(String[] args) {
|
||||
|
||||
try {
|
||||
for (int i = 0; i < args.length; ++i){
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
|
||||
// override the db directory
|
||||
if (args[i].equals("--help")){
|
||||
if (args[i].equals("--help")) {
|
||||
|
||||
printHelp();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// override the db directory
|
||||
if (args[i].equals("-db") && i + 1 < args.length){
|
||||
String db = args[i+1];
|
||||
if (args[i].equals("-db") && i + 1 < args.length) {
|
||||
String db = args[i + 1];
|
||||
logger.info("DB directory set to [{}]", db);
|
||||
CONFIG.setDataBaseDir(db);
|
||||
}
|
||||
|
||||
// override the listen port directory
|
||||
if (args[i].equals("-listen") && i + 1 < args.length){
|
||||
String port = args[i+1];
|
||||
if (args[i].equals("-listen") && i + 1 < args.length) {
|
||||
String port = args[i + 1];
|
||||
logger.info("Listen port set to [{}]", port);
|
||||
CONFIG.setListenPort(Integer.valueOf(port));
|
||||
}
|
||||
|
||||
// override the connect host:port directory
|
||||
if (args[i].equals("-connect") && i + 1 < args.length){
|
||||
String connectStr = args[i+1];
|
||||
if (args[i].equals("-connect") && i + 1 < args.length) {
|
||||
String connectStr = args[i + 1];
|
||||
logger.info("Connect host:port set to [{}]", connectStr);
|
||||
String[] params = connectStr.split(":");
|
||||
String host = params[0];
|
||||
@ -57,8 +57,8 @@ public class CLIInterface {
|
||||
}
|
||||
|
||||
// override the listen port directory
|
||||
if (args[i].equals("-reset") && i + 1 < args.length){
|
||||
Boolean resetStr = interpret( args[i+1] );
|
||||
if (args[i].equals("-reset") && i + 1 < args.length) {
|
||||
Boolean resetStr = interpret(args[i + 1]);
|
||||
logger.info("Resetting db set to [{}]", resetStr);
|
||||
CONFIG.setDatabaseReset(resetStr);
|
||||
}
|
||||
@ -70,7 +70,7 @@ public class CLIInterface {
|
||||
}
|
||||
}
|
||||
|
||||
private static Boolean interpret(String arg){
|
||||
private static Boolean interpret(String arg) {
|
||||
|
||||
if (arg.equals("on") || arg.equals("true") || arg.equals("yes")) return true;
|
||||
if (arg.equals("off") || arg.equals("false") || arg.equals("no")) return false;
|
||||
@ -78,7 +78,7 @@ public class CLIInterface {
|
||||
throw new Error("Can't interpret the answer: " + arg);
|
||||
}
|
||||
|
||||
private static void printHelp(){
|
||||
private static void printHelp() {
|
||||
|
||||
System.out.println("--help -- this help message ");
|
||||
System.out.println("-reset <yes/no> -- reset yes/no the all database ");
|
||||
|
@ -122,7 +122,7 @@ public class SystemProperties {
|
||||
return Boolean.parseBoolean(prop.getProperty("database.reset"));
|
||||
}
|
||||
|
||||
public void setDatabaseReset(Boolean reset){
|
||||
public void setDatabaseReset(Boolean reset) {
|
||||
prop.setProperty("database.reset", reset.toString());
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ public class SystemProperties {
|
||||
return prop.getProperty("peer.active.ip");
|
||||
}
|
||||
|
||||
public void setActivePeerIP(String host){
|
||||
public void setActivePeerIP(String host) {
|
||||
prop.setProperty("peer.active.ip", host.toString());
|
||||
}
|
||||
|
||||
@ -140,7 +140,7 @@ public class SystemProperties {
|
||||
return Integer.parseInt(prop.getProperty("peer.active.port"));
|
||||
}
|
||||
|
||||
public void setActivePeerPort(Integer port){
|
||||
public void setActivePeerPort(Integer port) {
|
||||
prop.setProperty("peer.active.port", port.toString());
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ public class SystemProperties {
|
||||
return prop.getProperty("database.dir");
|
||||
}
|
||||
|
||||
public void setDataBaseDir(String dataBaseDir){
|
||||
public void setDataBaseDir(String dataBaseDir) {
|
||||
prop.setProperty("database.dir", dataBaseDir);
|
||||
}
|
||||
|
||||
@ -247,13 +247,13 @@ public class SystemProperties {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public List<String> peerCapabilities(){
|
||||
public List<String> peerCapabilities() {
|
||||
if (prop.isEmpty()) return DEFAULT_PROTOCOL_LIST;
|
||||
String capabilitiesList = prop.getProperty("peer.capabilities");
|
||||
return Arrays.asList(capabilitiesList.split(","));
|
||||
}
|
||||
|
||||
public boolean vmTrace(){
|
||||
public boolean vmTrace() {
|
||||
if (prop.isEmpty()) return DEFAULT_VM_TRACE;
|
||||
return Boolean.parseBoolean(prop.getProperty("vm.structured.trace"));
|
||||
}
|
||||
@ -263,12 +263,12 @@ public class SystemProperties {
|
||||
return prop.getProperty("vm.structured.dir");
|
||||
}
|
||||
|
||||
public int listenPort(){
|
||||
public int listenPort() {
|
||||
if (prop.isEmpty()) return DEFAULT_PEER_LISTEN_PORT;
|
||||
return Integer.parseInt(prop.getProperty("peer.listen.port"));
|
||||
}
|
||||
|
||||
public void setListenPort(Integer port){
|
||||
public void setListenPort(Integer port) {
|
||||
prop.setProperty("peer.listen.port", port.toString());
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ public class Account {
|
||||
public Account() {
|
||||
}
|
||||
|
||||
public void init(){
|
||||
public void init() {
|
||||
this.ecKey = new ECKey(Utils.getRandom());
|
||||
address = this.ecKey.getAddress();
|
||||
}
|
||||
@ -40,14 +40,14 @@ public class Account {
|
||||
address = this.ecKey.getAddress();
|
||||
}
|
||||
|
||||
public BigInteger getNonce(){
|
||||
public BigInteger getNonce() {
|
||||
AccountState accountState =
|
||||
worldManager.getRepository().getAccountState(getAddress());
|
||||
|
||||
return accountState.getNonce();
|
||||
}
|
||||
|
||||
public BigInteger getBalance(){
|
||||
public BigInteger getBalance() {
|
||||
|
||||
AccountState accountState =
|
||||
worldManager.getRepository().getAccountState(this.getAddress());
|
||||
@ -57,15 +57,15 @@ public class Account {
|
||||
if (accountState != null)
|
||||
balance = accountState.getBalance();
|
||||
|
||||
synchronized (getPendingTransactins()){
|
||||
if (!getPendingTransactins().isEmpty()){
|
||||
synchronized (getPendingTransactins()) {
|
||||
if (!getPendingTransactins().isEmpty()) {
|
||||
|
||||
for (Transaction tx : getPendingTransactins()){
|
||||
if (Arrays.equals(getAddress(), tx.getSender())){
|
||||
for (Transaction tx : getPendingTransactins()) {
|
||||
if (Arrays.equals(getAddress(), tx.getSender())) {
|
||||
balance = balance.subtract(new BigInteger(1, tx.getValue()));
|
||||
}
|
||||
|
||||
if (Arrays.equals(getAddress(), tx.getReceiveAddress())){
|
||||
if (Arrays.equals(getAddress(), tx.getReceiveAddress())) {
|
||||
balance = balance.add(new BigInteger(1, tx.getValue()));
|
||||
}
|
||||
}
|
||||
@ -94,14 +94,14 @@ public class Account {
|
||||
return this.pendingTransactions;
|
||||
}
|
||||
|
||||
public void addPendingTransaction(Transaction transaction){
|
||||
synchronized (pendingTransactions){
|
||||
public void addPendingTransaction(Transaction transaction) {
|
||||
synchronized (pendingTransactions) {
|
||||
pendingTransactions.add(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearAllPendingTransactions(){
|
||||
synchronized (pendingTransactions){
|
||||
public void clearAllPendingTransactions() {
|
||||
synchronized (pendingTransactions) {
|
||||
pendingTransactions.clear();
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ public class AccountState {
|
||||
}
|
||||
|
||||
public byte[] getEncoded() {
|
||||
if(rlpEncoded == null) {
|
||||
if (rlpEncoded == null) {
|
||||
byte[] nonce = RLP.encodeBigInteger(this.nonce);
|
||||
byte[] balance = RLP.encodeBigInteger(this.balance);
|
||||
byte[] stateRoot = RLP.encodeElement(this.stateRoot);
|
||||
@ -143,7 +143,7 @@ public class AccountState {
|
||||
return deleted;
|
||||
}
|
||||
|
||||
public AccountState clone(){
|
||||
public AccountState clone() {
|
||||
AccountState accountState = new AccountState();
|
||||
|
||||
accountState.addToBalance(this.getBalance());
|
||||
|
@ -23,6 +23,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||
* (such blocks are known as uncles).
|
||||
*
|
||||
* www.ethereumJ.com
|
||||
*
|
||||
* @author Roman Mandeleil,
|
||||
* Nick Savers
|
||||
* Created on: 20/05/2014 10:44
|
||||
@ -69,7 +70,7 @@ public class Block {
|
||||
timestamp, extraData, nonce);
|
||||
|
||||
this.transactionsList = transactionsList;
|
||||
if (this.transactionsList == null){
|
||||
if (this.transactionsList == null) {
|
||||
this.transactionsList = new CopyOnWriteArrayList<Transaction>();
|
||||
}
|
||||
|
||||
@ -105,7 +106,7 @@ public class Block {
|
||||
this.parsed = true;
|
||||
}
|
||||
|
||||
public BlockHeader getHeader(){
|
||||
public BlockHeader getHeader() {
|
||||
if (!parsed) parseRLP();
|
||||
return this.header;
|
||||
}
|
||||
@ -162,7 +163,7 @@ public class Block {
|
||||
return this.header.getTxTrieRoot();
|
||||
}
|
||||
|
||||
public byte[] getLogBloom(){
|
||||
public byte[] getLogBloom() {
|
||||
if (!parsed) parseRLP();
|
||||
return this.header.getLogsBloom();
|
||||
}
|
||||
@ -243,7 +244,7 @@ public class Block {
|
||||
toStringBuff.append(header.toString());
|
||||
|
||||
toStringBuff.append("\nUncles [\n");
|
||||
for (BlockHeader uncle : getUncleList()){
|
||||
for (BlockHeader uncle : getUncleList()) {
|
||||
toStringBuff.append(uncle.toString());
|
||||
toStringBuff.append("\n");
|
||||
}
|
||||
@ -277,20 +278,21 @@ public class Block {
|
||||
for (int i = 0; i < txTransactions.size(); i++) {
|
||||
RLPElement transactionRaw = txTransactions.get(i);
|
||||
this.transactionsList.add(new Transaction(transactionRaw.getRLPData()));
|
||||
this.txsState.update(RLP.encodeInt(i) , transactionRaw.getRLPData());
|
||||
this.txsState.update(RLP.encodeInt(i), transactionRaw.getRLPData());
|
||||
}
|
||||
|
||||
String calculatedRoot = Hex.toHexString(txsState.getRootHash());
|
||||
if(!calculatedRoot.equals(Hex.toHexString(expectedRoot)))
|
||||
if (!calculatedRoot.equals(Hex.toHexString(expectedRoot)))
|
||||
logger.error("Added tx receipts don't match the given txsStateRoot");
|
||||
}
|
||||
|
||||
/**
|
||||
* check if param block is son of this block
|
||||
*
|
||||
* @param block - possible a son of this
|
||||
* @return - true if this block is parent of param block
|
||||
*/
|
||||
public boolean isParentOf(Block block){
|
||||
public boolean isParentOf(Block block) {
|
||||
return Arrays.areEqual(this.getHash(), block.getParentHash());
|
||||
}
|
||||
|
||||
@ -298,29 +300,29 @@ public class Block {
|
||||
return this.header.isGenesis();
|
||||
}
|
||||
|
||||
public boolean isEqual(Block block){
|
||||
public boolean isEqual(Block block) {
|
||||
return Arrays.areEqual(this.getHash(), block.getHash());
|
||||
}
|
||||
|
||||
private byte[] getUnclesEncoded(){
|
||||
private byte[] getUnclesEncoded() {
|
||||
|
||||
byte[][] unclesEncoded = new byte[uncleList.size()][];
|
||||
int i = 0;
|
||||
for( BlockHeader uncle : uncleList ){
|
||||
for (BlockHeader uncle : uncleList) {
|
||||
unclesEncoded[i] = uncle.getEncoded();
|
||||
++i;
|
||||
}
|
||||
return RLP.encodeList(unclesEncoded);
|
||||
}
|
||||
|
||||
public void addUncle(BlockHeader uncle){
|
||||
public void addUncle(BlockHeader uncle) {
|
||||
uncleList.add(uncle);
|
||||
this.getHeader().setUnclesHash( SHA3Helper.sha3( getUnclesEncoded() ));
|
||||
this.getHeader().setUnclesHash(SHA3Helper.sha3(getUnclesEncoded()));
|
||||
rlpEncoded = null;
|
||||
}
|
||||
|
||||
public byte[] getEncoded() {
|
||||
if(rlpEncoded == null) {
|
||||
if (rlpEncoded == null) {
|
||||
byte[] header = this.header.getEncoded();
|
||||
byte[] transactions = RLP.encodeList();
|
||||
byte[] uncles = getUnclesEncoded();
|
||||
@ -335,7 +337,7 @@ public class Block {
|
||||
return header;
|
||||
}
|
||||
|
||||
public String getShortHash(){
|
||||
public String getShortHash() {
|
||||
if (!parsed) parseRLP();
|
||||
return Hex.toHexString(getHash()).substring(0, 6);
|
||||
}
|
||||
|
@ -69,11 +69,11 @@ public class BlockHeader {
|
||||
this.stateRoot = rlpHeader.get(3).getRLPData();
|
||||
|
||||
this.txTrieRoot = rlpHeader.get(4).getRLPData();
|
||||
if(this.txTrieRoot == null)
|
||||
if (this.txTrieRoot == null)
|
||||
this.txTrieRoot = EMPTY_TRIE_HASH;
|
||||
|
||||
this.recieptTrieRoot = rlpHeader.get(5).getRLPData();
|
||||
if(this.recieptTrieRoot == null)
|
||||
if (this.recieptTrieRoot == null)
|
||||
this.recieptTrieRoot = EMPTY_TRIE_HASH;
|
||||
|
||||
this.logsBloom = rlpHeader.get(6).getRLPData();
|
||||
@ -117,6 +117,7 @@ public class BlockHeader {
|
||||
/**
|
||||
* Calculate Difficulty
|
||||
* See Yellow Paper: http://www.gavwood.com/Paper.pdf - page 5, 4.3.4 (24)
|
||||
*
|
||||
* @return byte array value of the difficulty
|
||||
*/
|
||||
public byte[] calcDifficulty() {
|
||||
@ -132,8 +133,6 @@ public class BlockHeader {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public boolean isGenesis() {
|
||||
return this.getNumber() == Genesis.NUMBER;
|
||||
}
|
||||
@ -141,79 +140,107 @@ public class BlockHeader {
|
||||
public byte[] getParentHash() {
|
||||
return parentHash;
|
||||
}
|
||||
|
||||
public void setParentHash(byte[] parentHash) {
|
||||
this.parentHash = parentHash;
|
||||
}
|
||||
|
||||
public byte[] getUnclesHash() {
|
||||
return unclesHash;
|
||||
}
|
||||
|
||||
public void setUnclesHash(byte[] unclesHash) {
|
||||
this.unclesHash = unclesHash;
|
||||
}
|
||||
|
||||
public byte[] getCoinbase() {
|
||||
return coinbase;
|
||||
}
|
||||
|
||||
public void setCoinbase(byte[] coinbase) {
|
||||
this.coinbase = coinbase;
|
||||
}
|
||||
|
||||
public byte[] getStateRoot() {
|
||||
return stateRoot;
|
||||
}
|
||||
|
||||
public void setStateRoot(byte[] stateRoot) {
|
||||
this.stateRoot = stateRoot;
|
||||
}
|
||||
|
||||
public byte[] getTxTrieRoot() {
|
||||
return txTrieRoot;
|
||||
}
|
||||
|
||||
public void setTxTrieRoot(byte[] txTrieRoot) {
|
||||
this.txTrieRoot = txTrieRoot;
|
||||
}
|
||||
|
||||
public byte[] getRecieptTrieRoot() {
|
||||
return recieptTrieRoot;
|
||||
}
|
||||
public byte[] getLogsBloom() {return logsBloom;}
|
||||
|
||||
public byte[] getLogsBloom() {
|
||||
return logsBloom;
|
||||
}
|
||||
|
||||
public void setRecieptTrieRoot(byte[] recieptTrieRoot) {
|
||||
this.recieptTrieRoot = recieptTrieRoot;
|
||||
}
|
||||
|
||||
public byte[] getDifficulty() {
|
||||
return difficulty;
|
||||
}
|
||||
|
||||
public void setDifficulty(byte[] difficulty) {
|
||||
this.difficulty = difficulty;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public long getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(long number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public long getGasLimit() {
|
||||
return gasLimit;
|
||||
}
|
||||
|
||||
public void setGasLimit(long gasLimit) {
|
||||
this.gasLimit = gasLimit;
|
||||
}
|
||||
|
||||
public long getGasUsed() {
|
||||
return gasUsed;
|
||||
}
|
||||
|
||||
public void setGasUsed(long gasUsed) {
|
||||
this.gasUsed = gasUsed;
|
||||
}
|
||||
|
||||
public byte[] getExtraData() {
|
||||
return extraData;
|
||||
}
|
||||
|
||||
public void setExtraData(byte[] extraData) {
|
||||
this.extraData = extraData;
|
||||
}
|
||||
|
||||
public byte[] getNonce() {
|
||||
return nonce;
|
||||
}
|
||||
|
||||
public void setNonce(byte[] nonce) {
|
||||
this.nonce = nonce;
|
||||
}
|
||||
@ -247,7 +274,7 @@ public class BlockHeader {
|
||||
byte[] gasUsed = RLP.encodeBigInteger(BigInteger.valueOf(this.gasUsed));
|
||||
byte[] timestamp = RLP.encodeBigInteger(BigInteger.valueOf(this.timestamp));
|
||||
byte[] extraData = RLP.encodeElement(this.extraData);
|
||||
if(withNonce) {
|
||||
if (withNonce) {
|
||||
byte[] nonce = RLP.encodeElement(this.nonce);
|
||||
return RLP.encodeList(parentHash, unclesHash, coinbase,
|
||||
stateRoot, txTrieRoot, recieptTrieRoot, logsBloom, difficulty, number,
|
||||
@ -260,7 +287,6 @@ public class BlockHeader {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private StringBuffer toStringBuff = new StringBuffer();
|
||||
|
||||
public String toString() {
|
||||
|
@ -54,6 +54,7 @@ import static org.ethereum.core.Denomination.SZABO;
|
||||
* See <a href="https://github.com/ethereum/wiki/wiki/White-Paper#blockchain-and-mining">Ethereum Whitepaper</a>
|
||||
*
|
||||
* www.etherJ.com
|
||||
*
|
||||
* @author Roman Mandeleil,
|
||||
* Nick Savers
|
||||
* Created on: 20/05/2014 10:44
|
||||
@ -119,23 +120,23 @@ public class BlockchainImpl implements Blockchain {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionReceipt getTransactionReceiptByHash(byte[] hash){
|
||||
public TransactionReceipt getTransactionReceiptByHash(byte[] hash) {
|
||||
|
||||
return blockStore.getTransactionReceiptByHash(hash);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Block getBlockByHash(byte[] hash){
|
||||
public Block getBlockByHash(byte[] hash) {
|
||||
return blockStore.getBlockByHash(hash);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<byte[]> getListOfHashesStartFrom(byte[] hash, int qty){
|
||||
public List<byte[]> getListOfHashesStartFrom(byte[] hash, int qty) {
|
||||
return blockStore.getListOfHashesStartFrom(hash, qty);
|
||||
}
|
||||
|
||||
|
||||
public void tryToConnect(Block block){
|
||||
public void tryToConnect(Block block) {
|
||||
|
||||
recordBlock(block);
|
||||
|
||||
@ -144,7 +145,7 @@ public class BlockchainImpl implements Blockchain {
|
||||
Hex.toHexString(block.getHash()).substring(0, 6),
|
||||
block.getNumber());
|
||||
|
||||
if (blockStore.getBlockByHash(block.getHash()) != null){
|
||||
if (blockStore.getBlockByHash(block.getHash()) != null) {
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Block already exist hash: {}, number: {}",
|
||||
@ -157,12 +158,12 @@ public class BlockchainImpl implements Blockchain {
|
||||
|
||||
// The simple case got the block
|
||||
// to connect to the main chain
|
||||
if (bestBlock.isParentOf(block)){
|
||||
if (bestBlock.isParentOf(block)) {
|
||||
add(block);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasParentOnTheChain(block) && block.getNumber() > bestBlock.getNumber()){
|
||||
if (!hasParentOnTheChain(block) && block.getNumber() > bestBlock.getNumber()) {
|
||||
|
||||
logger.info("*** Blockchain will rollback and resynchronise now ");
|
||||
|
||||
@ -222,7 +223,7 @@ public class BlockchainImpl implements Blockchain {
|
||||
|
||||
if (blockQueue.size() == 0 &&
|
||||
!syncDoneCalled &&
|
||||
channelManager.isAllSync()){
|
||||
channelManager.isAllSync()) {
|
||||
|
||||
logger.info("Sync done");
|
||||
syncDoneCalled = true;
|
||||
@ -231,7 +232,7 @@ public class BlockchainImpl implements Blockchain {
|
||||
}
|
||||
|
||||
|
||||
public Block getParent(BlockHeader header){
|
||||
public Block getParent(BlockHeader header) {
|
||||
|
||||
return blockStore.getBlockByHash(header.getParentHash());
|
||||
}
|
||||
@ -239,6 +240,7 @@ public class BlockchainImpl implements Blockchain {
|
||||
/**
|
||||
* Calculate GasLimit
|
||||
* See Yellow Paper: http://www.gavwood.com/Paper.pdf - page 5, 4.3.4 (25)
|
||||
*
|
||||
* @return long value of the gasLimit
|
||||
*/
|
||||
public long calcGasLimit(BlockHeader header) {
|
||||
@ -272,12 +274,12 @@ public class BlockchainImpl implements Blockchain {
|
||||
* likely next period. Conversely, if the period is too large, the difficulty,
|
||||
* and expected time to the next block, is reduced.
|
||||
*/
|
||||
private boolean isValid(Block block){
|
||||
private boolean isValid(Block block) {
|
||||
|
||||
boolean isValid = true;
|
||||
if (isValid) return (isValid); // todo get back to the real header validation
|
||||
|
||||
if(!block.isGenesis()) {
|
||||
if (!block.isGenesis()) {
|
||||
isValid = isValid(block.getHeader());
|
||||
|
||||
for (BlockHeader uncle : block.getUncleList()) {
|
||||
@ -291,7 +293,7 @@ public class BlockchainImpl implements Blockchain {
|
||||
isValid = generationGap > 0 && generationGap < 7;
|
||||
}
|
||||
}
|
||||
if(!isValid)
|
||||
if (!isValid)
|
||||
logger.warn("WARNING: Invalid - {}", this);
|
||||
return isValid;
|
||||
|
||||
@ -300,7 +302,7 @@ public class BlockchainImpl implements Blockchain {
|
||||
private void processBlock(Block block) {
|
||||
|
||||
List<TransactionReceipt> receipts = new ArrayList<>();
|
||||
if(isValid(block)) {
|
||||
if (isValid(block)) {
|
||||
if (!block.isGenesis()) {
|
||||
if (!CONFIG.blockChainOnly()) {
|
||||
wallet.addTransactions(block.getTransactionsList());
|
||||
@ -341,9 +343,9 @@ public class BlockchainImpl implements Blockchain {
|
||||
stateLogger.info("[{}] ", receipt.toString());
|
||||
|
||||
if (stateLogger.isInfoEnabled())
|
||||
stateLogger.info("tx[{}].receipt: [{}] ",i, Hex.toHexString(receipt.getEncoded()));
|
||||
stateLogger.info("tx[{}].receipt: [{}] ", i, Hex.toHexString(receipt.getEncoded()));
|
||||
|
||||
if(block.getNumber() >= CONFIG.traceStartBlock())
|
||||
if (block.getNumber() >= CONFIG.traceStartBlock())
|
||||
repository.dumpState(block, totalGasUsed, i++, tx.getHash());
|
||||
|
||||
reciepts.add(receipt);
|
||||
@ -354,7 +356,7 @@ public class BlockchainImpl implements Blockchain {
|
||||
|
||||
track.commit();
|
||||
|
||||
if(block.getNumber() >= CONFIG.traceStartBlock())
|
||||
if (block.getNumber() >= CONFIG.traceStartBlock())
|
||||
repository.dumpState(block, totalGasUsed, 0, null);
|
||||
|
||||
return reciepts;
|
||||
@ -372,7 +374,7 @@ public class BlockchainImpl implements Blockchain {
|
||||
BigInteger totalBlockReward = Block.BLOCK_REWARD;
|
||||
|
||||
// Add extra rewards based on number of uncles
|
||||
if(block.getUncleList().size() > 0) {
|
||||
if (block.getUncleList().size() > 0) {
|
||||
for (BlockHeader uncle : block.getUncleList()) {
|
||||
track.addBalance(uncle.getCoinbase(), Block.UNCLE_REWARD);
|
||||
}
|
||||
@ -386,10 +388,10 @@ public class BlockchainImpl implements Blockchain {
|
||||
public void storeBlock(Block block, List<TransactionReceipt> receipts) {
|
||||
|
||||
/* Debug check to see if the state is still as expected */
|
||||
if(logger.isWarnEnabled()) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
String blockStateRootHash = Hex.toHexString(block.getStateRoot());
|
||||
String worldStateRootHash = Hex.toHexString(repository.getRoot());
|
||||
if(!blockStateRootHash.equals(worldStateRootHash)){
|
||||
if (!blockStateRootHash.equals(worldStateRootHash)) {
|
||||
|
||||
stateLogger.info("BLOCK: STATE CONFLICT! block: {} worldstate {} mismatch", block.getNumber(), worldStateRootHash);
|
||||
adminInfo.lostConsensus();
|
||||
@ -411,17 +413,17 @@ public class BlockchainImpl implements Blockchain {
|
||||
}
|
||||
|
||||
|
||||
public boolean hasParentOnTheChain(Block block){
|
||||
public boolean hasParentOnTheChain(Block block) {
|
||||
return getParent(block.getHeader()) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Chain> getAltChains(){
|
||||
public List<Chain> getAltChains() {
|
||||
return altChains;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Block> getGarbage(){
|
||||
public List<Block> getGarbage() {
|
||||
return garbage;
|
||||
}
|
||||
|
||||
@ -442,14 +444,14 @@ public class BlockchainImpl implements Blockchain {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(){
|
||||
public void reset() {
|
||||
blockStore.reset();
|
||||
altChains = new ArrayList<>();
|
||||
garbage = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(){
|
||||
public void close() {
|
||||
blockQueue.close();
|
||||
}
|
||||
|
||||
@ -468,12 +470,15 @@ public class BlockchainImpl implements Blockchain {
|
||||
this.totalDifficulty = totalDifficulty;
|
||||
}
|
||||
|
||||
private void recordBlock(Block block){
|
||||
private void recordBlock(Block block) {
|
||||
|
||||
if (!CONFIG.recordBlocks()) return;
|
||||
|
||||
if (bestBlock.isGenesis()){
|
||||
try {FileUtils.deleteDirectory(CONFIG.dumpDir());} catch (IOException e) {}
|
||||
if (bestBlock.isGenesis()) {
|
||||
try {
|
||||
FileUtils.deleteDirectory(CONFIG.dumpDir());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
String dir = CONFIG.dumpDir() + "/";
|
||||
@ -490,7 +495,7 @@ public class BlockchainImpl implements Blockchain {
|
||||
fw = new FileWriter(dumpFile.getAbsoluteFile(), true);
|
||||
bw = new BufferedWriter(fw);
|
||||
|
||||
if (bestBlock.isGenesis()){
|
||||
if (bestBlock.isGenesis()) {
|
||||
bw.write(Hex.toHexString(bestBlock.getEncoded()));
|
||||
bw.write("\n");
|
||||
}
|
||||
@ -516,15 +521,15 @@ public class BlockchainImpl implements Blockchain {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public void setProgramInvokeFactory(ProgramInvokeFactory factory){
|
||||
public void setProgramInvokeFactory(ProgramInvokeFactory factory) {
|
||||
this.programInvokeFactory = factory;
|
||||
}
|
||||
|
||||
public void startTracking(){
|
||||
public void startTracking() {
|
||||
track = repository.startTracking();
|
||||
}
|
||||
|
||||
public void commitTracking(){
|
||||
public void commitTracking() {
|
||||
track.commit();
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ public class Bloom {
|
||||
public Bloom() {
|
||||
}
|
||||
|
||||
public Bloom(byte[] data){
|
||||
public Bloom(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@ -41,8 +41,8 @@ public class Bloom {
|
||||
return bloom;
|
||||
}
|
||||
|
||||
public void or(Bloom bloom){
|
||||
for (int i = 0; i < data.length; ++i){
|
||||
public void or(Bloom bloom) {
|
||||
for (int i = 0; i < data.length; ++i) {
|
||||
data[i] |= bloom.data[i];
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class Chain {
|
||||
private Map<ByteArrayWrapper, Block> index = new HashMap<>();
|
||||
|
||||
|
||||
public boolean tryToConnect(Block block){
|
||||
public boolean tryToConnect(Block block) {
|
||||
|
||||
if (chain.isEmpty()) {
|
||||
add(block);
|
||||
@ -35,14 +35,14 @@ public class Chain {
|
||||
}
|
||||
|
||||
Block lastBlock = chain.get(chain.size() - 1);
|
||||
if (lastBlock.isParentOf(block)){
|
||||
if (lastBlock.isParentOf(block)) {
|
||||
add(block);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void add(Block block){
|
||||
public void add(Block block) {
|
||||
logger.info("adding block to alt chain block.hash: [{}] ", block.getShortHash());
|
||||
totalDifficulty = totalDifficulty.add(block.getCumulativeDifficulty());
|
||||
logger.info("total difficulty on alt chain is: [{}] ", totalDifficulty);
|
||||
@ -50,15 +50,15 @@ public class Chain {
|
||||
index.put(new ByteArrayWrapper(block.getHash()), block);
|
||||
}
|
||||
|
||||
public Block get(int i){
|
||||
public Block get(int i) {
|
||||
return chain.get(i);
|
||||
}
|
||||
|
||||
public Block getLast(){
|
||||
public Block getLast() {
|
||||
return chain.get(chain.size() - 1);
|
||||
}
|
||||
|
||||
public BigInteger getTotalDifficulty(){
|
||||
public BigInteger getTotalDifficulty() {
|
||||
return totalDifficulty;
|
||||
}
|
||||
|
||||
@ -66,11 +66,11 @@ public class Chain {
|
||||
this.totalDifficulty = totalDifficulty;
|
||||
}
|
||||
|
||||
public boolean isParentOnTheChain(Block block){
|
||||
return (index.get(new ByteArrayWrapper( block.getParentHash() )) != null);
|
||||
public boolean isParentOnTheChain(Block block) {
|
||||
return (index.get(new ByteArrayWrapper(block.getParentHash())) != null);
|
||||
}
|
||||
|
||||
public long getSize(){
|
||||
public long getSize() {
|
||||
return chain.size();
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ public class Genesis extends Block {
|
||||
|
||||
public final static BigInteger PREMINE_AMOUNT = BigInteger.valueOf(2).pow(200);
|
||||
|
||||
private static String[] premine = new String[] {
|
||||
private static String[] premine = new String[]{
|
||||
"51ba59315b3a95761d0863b05ccc7a7f54703d99",
|
||||
"e6716f9544a56c530d868e4bfbacb172315bdead", // # (J)
|
||||
"b9c015918bdaba24b4ff057a92a3873d6eb201be", // # (V)
|
||||
|
@ -10,6 +10,7 @@ import org.ethereum.util.RLPList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.util.BigIntegers;
|
||||
|
||||
import java.security.SignatureException;
|
||||
|
||||
import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY;
|
||||
@ -86,7 +87,7 @@ public class Transaction {
|
||||
this.value = value;
|
||||
this.data = data;
|
||||
|
||||
if(receiveAddress == null) {
|
||||
if (receiveAddress == null) {
|
||||
this.receiveAddress = ByteUtil.EMPTY_BYTE_ARRAY;
|
||||
}
|
||||
|
||||
@ -106,7 +107,7 @@ public class Transaction {
|
||||
this.value = transaction.get(4).getRLPData();
|
||||
this.data = transaction.get(5).getRLPData();
|
||||
// only parse signature in case tx is signed
|
||||
if(transaction.get(6).getRLPData() != null) {
|
||||
if (transaction.get(6).getRLPData() != null) {
|
||||
byte v = transaction.get(6).getRLPData()[0];
|
||||
byte[] r = transaction.get(7).getRLPData();
|
||||
byte[] s = transaction.get(8).getRLPData();
|
||||
@ -158,7 +159,7 @@ public class Transaction {
|
||||
|
||||
public byte[] getGasPrice() {
|
||||
if (!parsed) rlpParse();
|
||||
return gasPrice== null ? ZERO_BYTE_ARRAY : gasPrice;
|
||||
return gasPrice == null ? ZERO_BYTE_ARRAY : gasPrice;
|
||||
}
|
||||
|
||||
public byte[] getGasLimit() {
|
||||
@ -166,7 +167,7 @@ public class Transaction {
|
||||
return gasLimit;
|
||||
}
|
||||
|
||||
public long nonZeroDataBytes(){
|
||||
public long nonZeroDataBytes() {
|
||||
if (data == null) return 0;
|
||||
int counter = 0;
|
||||
for (final byte aData : data) {
|
||||
@ -175,7 +176,7 @@ public class Transaction {
|
||||
return counter;
|
||||
}
|
||||
|
||||
public long zeroDataBytes(){
|
||||
public long zeroDataBytes() {
|
||||
if (data == null) return 0;
|
||||
int counter = 0;
|
||||
for (final byte aData : data) {
|
||||
@ -261,7 +262,7 @@ public class Transaction {
|
||||
|
||||
// parse null as 0 for nonce
|
||||
byte[] nonce = null;
|
||||
if ( this.nonce == null || this.nonce.length == 1 && this.nonce[0] == 0){
|
||||
if (this.nonce == null || this.nonce.length == 1 && this.nonce[0] == 0) {
|
||||
nonce = RLP.encodeElement(null);
|
||||
} else {
|
||||
nonce = RLP.encodeElement(this.nonce);
|
||||
@ -279,11 +280,11 @@ public class Transaction {
|
||||
|
||||
public byte[] getEncoded() {
|
||||
|
||||
if(rlpEncoded != null) return rlpEncoded;
|
||||
if (rlpEncoded != null) return rlpEncoded;
|
||||
|
||||
// parse null as 0 for nonce
|
||||
byte[] nonce = null;
|
||||
if (this.nonce == null || this.nonce.length == 1 && this.nonce[0] == 0){
|
||||
if (this.nonce == null || this.nonce.length == 1 && this.nonce[0] == 0) {
|
||||
nonce = RLP.encodeElement(null);
|
||||
} else {
|
||||
nonce = RLP.encodeElement(this.nonce);
|
||||
@ -296,8 +297,8 @@ public class Transaction {
|
||||
|
||||
byte[] v, r, s;
|
||||
|
||||
if(signature != null) {
|
||||
v = RLP.encodeByte( signature.v );
|
||||
if (signature != null) {
|
||||
v = RLP.encodeByte(signature.v);
|
||||
r = RLP.encodeElement(BigIntegers.asUnsignedByteArray(signature.r));
|
||||
s = RLP.encodeElement(BigIntegers.asUnsignedByteArray(signature.s));
|
||||
} else {
|
||||
@ -331,7 +332,7 @@ public class Transaction {
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (!(obj instanceof Transaction)) return false;
|
||||
Transaction tx = (Transaction)obj;
|
||||
Transaction tx = (Transaction) obj;
|
||||
|
||||
return tx.hashCode() == this.hashCode();
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public class TransactionExecutor {
|
||||
// https://github.com/ethereum/cpp-ethereum/blob/develop/libethereum/Executive.cpp#L55
|
||||
|
||||
|
||||
public void execute(){
|
||||
public void execute() {
|
||||
|
||||
|
||||
logger.info("applyTransaction: [{}]", Hex.toHexString(tx.getHash()));
|
||||
@ -166,8 +166,8 @@ public class TransactionExecutor {
|
||||
try {
|
||||
|
||||
// CREATE NEW CONTRACT ADDRESS AND ADD TX VALUE
|
||||
if(isContractCreation) {
|
||||
if(stateLogger.isDebugEnabled())
|
||||
if (isContractCreation) {
|
||||
if (stateLogger.isDebugEnabled())
|
||||
stateLogger.debug("new contract created address={}",
|
||||
Hex.toHexString(receiverAddress));
|
||||
}
|
||||
@ -199,7 +199,7 @@ public class TransactionExecutor {
|
||||
trackTx.commit();
|
||||
} else {
|
||||
// REFUND GASDEBIT EXCEPT FOR FEE (500 + 5*TX_NO_ZERO_DATA)
|
||||
long dataCost = tx.getData() == null ? 0:
|
||||
long dataCost = tx.getData() == null ? 0 :
|
||||
tx.nonZeroDataBytes() * GasCost.TX_NO_ZERO_DATA +
|
||||
tx.zeroDataBytes() * GasCost.TX_ZERO_DATA;
|
||||
gasUsed = GasCost.TRANSACTION + dataCost;
|
||||
@ -253,7 +253,7 @@ public class TransactionExecutor {
|
||||
repository.addBalance(coinbase, refund.negate());
|
||||
}
|
||||
|
||||
if (result.getFutureRefund() > 0){
|
||||
if (result.getFutureRefund() > 0) {
|
||||
|
||||
long futureRefund = Math.min(result.getFutureRefund(), result.getGasUsed() / 2);
|
||||
BigInteger futureRefundBI = BigInteger.valueOf(futureRefund);
|
||||
@ -284,11 +284,12 @@ public class TransactionExecutor {
|
||||
Hex.toHexString(contractAddress),
|
||||
Hex.toHexString(bodyCode));
|
||||
|
||||
BigInteger storageCost = gasPrice.multiply( BigInteger.valueOf( bodyCode.length * GasCost.CREATE_DATA_BYTE) );
|
||||
BigInteger storageCost = gasPrice.multiply(BigInteger.valueOf(bodyCode.length * GasCost
|
||||
.CREATE_DATA_BYTE));
|
||||
BigInteger balance = repository.getBalance(senderAddress);
|
||||
|
||||
// check if can be charged for the contract data save
|
||||
if (storageCost.compareTo(balance) > 1){
|
||||
if (storageCost.compareTo(balance) > 1) {
|
||||
bodyCode = EMPTY_BYTE_ARRAY;
|
||||
} else {
|
||||
repository.addBalance(coinbase, storageCost);
|
||||
@ -301,7 +302,7 @@ public class TransactionExecutor {
|
||||
|
||||
// delete the marked to die accounts
|
||||
if (result.getDeleteAccounts() == null) return;
|
||||
for (DataWord address : result.getDeleteAccounts()){
|
||||
for (DataWord address : result.getDeleteAccounts()) {
|
||||
repository.delete(address.getNoLeadZeroesData());
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,6 @@ import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY;
|
||||
* 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,
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class TransactionReceipt {
|
||||
|
||||
@ -92,7 +90,7 @@ public class TransactionReceipt {
|
||||
/* [postTxState, cumulativeGas, bloomFilter, logInfoList] */
|
||||
public byte[] getEncoded() {
|
||||
|
||||
if(rlpEncoded != null) return rlpEncoded;
|
||||
if (rlpEncoded != null) return rlpEncoded;
|
||||
|
||||
byte[] postTxStateRLP = RLP.encodeElement(this.postTxState);
|
||||
byte[] cumulativeGasRLP = RLP.encodeElement(this.cumulativeGas);
|
||||
@ -104,11 +102,11 @@ public class TransactionReceipt {
|
||||
|
||||
int i = 0;
|
||||
for (LogInfo logInfo : logInfoList) {
|
||||
logInfoListE[i] = logInfo.getEncoded() ;
|
||||
logInfoListE[i] = logInfo.getEncoded();
|
||||
++i;
|
||||
}
|
||||
logInfoListRLP = RLP.encodeList(logInfoListE);
|
||||
} else{
|
||||
} else {
|
||||
logInfoListRLP = RLP.encodeList();
|
||||
}
|
||||
|
||||
@ -122,7 +120,7 @@ public class TransactionReceipt {
|
||||
}
|
||||
|
||||
public void setCumulativeGas(long cumulativeGas) {
|
||||
this.cumulativeGas = BigIntegers.asUnsignedByteArray( BigInteger.valueOf( cumulativeGas ) );
|
||||
this.cumulativeGas = BigIntegers.asUnsignedByteArray(BigInteger.valueOf(cumulativeGas));
|
||||
}
|
||||
|
||||
public void setCumulativeGas(byte[] cumulativeGas) {
|
||||
@ -135,16 +133,16 @@ public class TransactionReceipt {
|
||||
this.rlpEncoded = null;
|
||||
this.logInfoList = logInfoList;
|
||||
|
||||
for (LogInfo loginfo : logInfoList){
|
||||
for (LogInfo loginfo : logInfoList) {
|
||||
bloomFilter.or(loginfo.getBloom());
|
||||
}
|
||||
}
|
||||
|
||||
public void setTransaction(Transaction transaction){
|
||||
public void setTransaction(Transaction transaction) {
|
||||
this.transaction = transaction;
|
||||
}
|
||||
|
||||
public Transaction getTransaction(){
|
||||
public Transaction getTransaction() {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ public class Wallet {
|
||||
* @param transaction
|
||||
* @return
|
||||
*/
|
||||
public WalletTransaction addByWalletTransaction(Transaction transaction){
|
||||
public WalletTransaction addByWalletTransaction(Transaction transaction) {
|
||||
String hash = Hex.toHexString(transaction.getHash());
|
||||
WalletTransaction walletTransaction = new WalletTransaction(transaction);
|
||||
this.walletTransactions.put(hash, walletTransaction);
|
||||
@ -127,7 +127,7 @@ public class Wallet {
|
||||
*/
|
||||
public WalletTransaction addTransaction(Transaction transaction) {
|
||||
String hash = Hex.toHexString(transaction.getHash());
|
||||
logger.info("pending transaction placed hash: {}", hash );
|
||||
logger.info("pending transaction placed hash: {}", hash);
|
||||
|
||||
WalletTransaction walletTransaction = this.walletTransactions.get(hash);
|
||||
if (walletTransaction != null)
|
||||
@ -178,7 +178,7 @@ public class Wallet {
|
||||
}
|
||||
|
||||
byte[] receiveAddress = transaction.getReceiveAddress();
|
||||
if(receiveAddress != null) {
|
||||
if (receiveAddress != null) {
|
||||
Account receiver = rows.get(Hex.toHexString(receiveAddress));
|
||||
if (receiver != null) {
|
||||
receiver.addPendingTransaction(transaction);
|
||||
@ -195,7 +195,7 @@ public class Wallet {
|
||||
|
||||
public void processBlock(Block block) {
|
||||
|
||||
for (Account account : getAccountCollection()){
|
||||
for (Account account : getAccountCollection()) {
|
||||
account.clearAllPendingTransactions();
|
||||
}
|
||||
|
||||
@ -237,7 +237,7 @@ public class Wallet {
|
||||
|
||||
NodeList rowNodes = walletNode.getChildNodes();
|
||||
|
||||
for (int i = 0; i < rowNodes.getLength(); ++i ) {
|
||||
for (int i = 0; i < rowNodes.getLength(); ++i) {
|
||||
|
||||
Node rowNode = rowNodes.item(i);
|
||||
Node addrNode = rowNode.getChildNodes().item(0);
|
||||
@ -287,7 +287,7 @@ public class Wallet {
|
||||
doc.appendChild(walletElement);
|
||||
|
||||
Attr high = doc.createAttribute("high");
|
||||
high.setValue(Long.toString( this.high ));
|
||||
high.setValue(Long.toString(this.high));
|
||||
walletElement.setAttributeNode(high);
|
||||
|
||||
int i = 0;
|
||||
@ -334,7 +334,7 @@ public class Wallet {
|
||||
listener.valueChanged();
|
||||
}
|
||||
|
||||
public interface WalletListener{
|
||||
public interface WalletListener {
|
||||
public void valueChanged();
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ package org.ethereum.crypto;
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import static org.ethereum.util.ByteUtil.bigIntegerToBytes;
|
||||
|
||||
import java.io.Serializable;
|
||||
@ -66,12 +67,15 @@ import org.spongycastle.util.encoders.Hex;
|
||||
* can usually ignore the compressed/uncompressed distinction.</p>
|
||||
*
|
||||
* This code is borrowed from the bitcoinj project and altered to fit Ethereum.<br>
|
||||
* See <a href="https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/com/google/bitcoin/core/ECKey.java">bitcoinj on GitHub</a>
|
||||
* See <a href="https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/com/google/bitcoin/core/ECKey
|
||||
* .java">bitcoinj on GitHub</a>
|
||||
*/
|
||||
public class ECKey implements Serializable {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ECKey.class);
|
||||
|
||||
/** The parameters of the secp256k1 curve that Ethereum uses. */
|
||||
/**
|
||||
* The parameters of the secp256k1 curve that Ethereum uses.
|
||||
*/
|
||||
public static final ECDomainParameters CURVE;
|
||||
|
||||
/**
|
||||
@ -125,7 +129,7 @@ public class ECKey implements Serializable {
|
||||
|
||||
public ECKey(@Nullable BigInteger priv, ECPoint pub) {
|
||||
this.priv = priv;
|
||||
if(pub == null)
|
||||
if (pub == null)
|
||||
throw new IllegalArgumentException("Public key may not be null");
|
||||
this.pub = pub;
|
||||
}
|
||||
@ -234,7 +238,9 @@ public class ECKey implements Serializable {
|
||||
return point.getEncoded(compressed);
|
||||
}
|
||||
|
||||
/** Gets the hash160 form of the public key (as seen in addresses). */
|
||||
/**
|
||||
* Gets the hash160 form of the public key (as seen in addresses).
|
||||
*/
|
||||
public byte[] getAddress() {
|
||||
if (pubKeyHash == null) {
|
||||
byte[] pubBytes = this.pub.getEncoded(false);
|
||||
@ -251,7 +257,9 @@ public class ECKey implements Serializable {
|
||||
return pub.getEncoded();
|
||||
}
|
||||
|
||||
/** Gets the public key in the form of an elliptic curve point object from Bouncy Castle. */
|
||||
/**
|
||||
* Gets the public key in the form of an elliptic curve point object from Bouncy Castle.
|
||||
*/
|
||||
public ECPoint getPubKeyPoint() {
|
||||
return pub;
|
||||
}
|
||||
@ -300,7 +308,9 @@ public class ECKey implements Serializable {
|
||||
* components can be useful for doing further EC maths on them.
|
||||
*/
|
||||
public static class ECDSASignature {
|
||||
/** The two components of the signature. */
|
||||
/**
|
||||
* The two components of the signature.
|
||||
*/
|
||||
public final BigInteger r, s;
|
||||
public byte v;
|
||||
|
||||
@ -601,11 +611,13 @@ public class ECKey implements Serializable {
|
||||
return ECKey.fromPublicOnly(q.getEncoded(compressed));
|
||||
}
|
||||
|
||||
/** Decompress a compressed public key (x co-ord and low-bit of y-coord). */
|
||||
/**
|
||||
* Decompress a compressed public key (x co-ord and low-bit of y-coord).
|
||||
*/
|
||||
private static ECPoint decompressKey(BigInteger xBN, boolean yBit) {
|
||||
X9IntegerConverter x9 = new X9IntegerConverter();
|
||||
byte[] compEnc = x9.integerToBytes(xBN, 1 + x9.getByteLength(CURVE.getCurve()));
|
||||
compEnc[0] = (byte)(yBit ? 0x03 : 0x02);
|
||||
compEnc[0] = (byte) (yBit ? 0x03 : 0x02);
|
||||
return CURVE.getCurve().decodePoint(compEnc);
|
||||
}
|
||||
|
||||
@ -643,6 +655,6 @@ public class ECKey implements Serializable {
|
||||
}
|
||||
|
||||
private static void check(boolean test, String message) {
|
||||
if(!test) throw new IllegalArgumentException(message);
|
||||
if (!test) throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ public class HashUtil {
|
||||
public static byte[] sha3(byte[] input) {
|
||||
ByteArrayWrapper inputByteArray = new ByteArrayWrapper(input);
|
||||
byte[] result = sha3Cache.get(inputByteArray);
|
||||
if(result != null)
|
||||
if (result != null)
|
||||
return result;
|
||||
result = SHA3Helper.sha3(input);
|
||||
sha3Cache.put(inputByteArray, result);
|
||||
|
@ -20,7 +20,7 @@ import java.util.List;
|
||||
* Created on: 12/11/2014 17:16
|
||||
*/
|
||||
@Repository
|
||||
@Transactional(propagation= Propagation.SUPPORTS)
|
||||
@Transactional(propagation = Propagation.SUPPORTS)
|
||||
public class BlockStore {
|
||||
|
||||
@Autowired
|
||||
@ -38,7 +38,7 @@ public class BlockStore {
|
||||
setParameter("number", blockNumber).list();
|
||||
|
||||
if (result.size() == 0) return null;
|
||||
BlockVO vo = (BlockVO)result.get(0);
|
||||
BlockVO vo = (BlockVO) result.get(0);
|
||||
|
||||
return new Block(vo.rlp);
|
||||
}
|
||||
@ -51,7 +51,7 @@ public class BlockStore {
|
||||
setParameter("hash", hash).list();
|
||||
|
||||
if (result.size() == 0) return null;
|
||||
BlockVO vo = (BlockVO)result.get(0);
|
||||
BlockVO vo = (BlockVO) result.get(0);
|
||||
|
||||
return new Block(vo.rlp);
|
||||
}
|
||||
@ -72,7 +72,7 @@ public class BlockStore {
|
||||
setParameter("limit", block.getNumber() - qty).
|
||||
setMaxResults(qty).list();
|
||||
|
||||
for (byte[] h : result){
|
||||
for (byte[] h : result) {
|
||||
hashes.add(h);
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ public class BlockStore {
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteBlocksSince(long number){
|
||||
public void deleteBlocksSince(long number) {
|
||||
|
||||
sessionFactory.getCurrentSession().
|
||||
createQuery("delete from BlockVO where number > :number").
|
||||
@ -95,7 +95,7 @@ public class BlockStore {
|
||||
BlockVO blockVO = new BlockVO(block.getNumber(), block.getHash(),
|
||||
block.getEncoded(), block.getCumulativeDifficulty());
|
||||
|
||||
for (TransactionReceipt receipt : receipts){
|
||||
for (TransactionReceipt receipt : receipts) {
|
||||
|
||||
byte[] hash = receipt.getTransaction().getHash();
|
||||
byte[] rlp = receipt.getEncoded();
|
||||
@ -108,9 +108,9 @@ public class BlockStore {
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public BigInteger getTotalDifficultySince(long number){
|
||||
public BigInteger getTotalDifficultySince(long number) {
|
||||
|
||||
BigInteger result = (BigInteger)sessionFactory.getCurrentSession().
|
||||
BigInteger result = (BigInteger) sessionFactory.getCurrentSession().
|
||||
createQuery("select sum(cummulativeDifficulty) from BlockVO where number > :number").
|
||||
setParameter("number", number).
|
||||
uniqueResult();
|
||||
@ -120,9 +120,9 @@ public class BlockStore {
|
||||
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public BigInteger getTotalDifficulty(){
|
||||
public BigInteger getTotalDifficulty() {
|
||||
|
||||
BigInteger result = (BigInteger)sessionFactory.getCurrentSession().
|
||||
BigInteger result = (BigInteger) sessionFactory.getCurrentSession().
|
||||
createQuery("select sum(cummulativeDifficulty) from BlockVO").uniqueResult();
|
||||
|
||||
return result;
|
||||
@ -130,15 +130,15 @@ public class BlockStore {
|
||||
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Block getBestBlock(){
|
||||
public Block getBestBlock() {
|
||||
|
||||
Long bestNumber = (Long)
|
||||
sessionFactory.getCurrentSession().createQuery("select max(number) from BlockVO").uniqueResult();
|
||||
List result = sessionFactory.getCurrentSession().
|
||||
createQuery("from BlockVO where number = :number").setParameter("number", bestNumber) .list();
|
||||
createQuery("from BlockVO where number = :number").setParameter("number", bestNumber).list();
|
||||
|
||||
if (result.isEmpty()) return null;
|
||||
BlockVO vo = (BlockVO)result.get(0);
|
||||
BlockVO vo = (BlockVO) result.get(0);
|
||||
|
||||
return new Block(vo.rlp);
|
||||
}
|
||||
@ -151,7 +151,7 @@ public class BlockStore {
|
||||
createQuery("from BlockVO").list();
|
||||
|
||||
ArrayList<Block> blocks = new ArrayList<>();
|
||||
for (BlockVO blockVO : (List<BlockVO>)result){
|
||||
for (BlockVO blockVO : (List<BlockVO>) result) {
|
||||
blocks.add(new Block(blockVO.getRlp()));
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ public class BlockStore {
|
||||
setParameter("hash", hash).list();
|
||||
|
||||
if (result.size() == 0) return null;
|
||||
TransactionReceiptVO vo = (TransactionReceiptVO)result.get(0);
|
||||
TransactionReceiptVO vo = (TransactionReceiptVO) result.get(0);
|
||||
|
||||
return new TransactionReceipt(vo.rlp);
|
||||
|
||||
|
@ -75,8 +75,7 @@ public class ContractDetails {
|
||||
if (foundIndex != -1) {
|
||||
DataWord value = storageValues.get(foundIndex);
|
||||
return value.clone();
|
||||
}
|
||||
else
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -94,7 +93,7 @@ public class ContractDetails {
|
||||
|
||||
storageTrie = new TrieImpl(null);
|
||||
// calc the trie for root hash
|
||||
for (int i = 0; i < storageKeys.size(); ++i){
|
||||
for (int i = 0; i < storageKeys.size(); ++i) {
|
||||
storageTrie.update(storageKeys.get(i).getData(), RLP
|
||||
.encodeElement(storageValues.get(i).getNoLeadZeroesData()));
|
||||
}
|
||||
@ -197,7 +196,7 @@ public class ContractDetails {
|
||||
keys.addAll(storageKeys);
|
||||
|
||||
List<DataWord> values = new ArrayList<>();
|
||||
for (DataWord key : keys){
|
||||
for (DataWord key : keys) {
|
||||
|
||||
DataWord value = storage.get(key);
|
||||
values.add(value);
|
||||
@ -208,18 +207,17 @@ public class ContractDetails {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ContractDetails clone(){
|
||||
public ContractDetails clone() {
|
||||
|
||||
ContractDetails contractDetails = new ContractDetails();
|
||||
|
||||
contractDetails.setCode(this.getCode());
|
||||
contractDetails.setStorage(new ArrayList<DataWord>(this.storageKeys) ,
|
||||
contractDetails.setStorage(new ArrayList<DataWord>(this.storageKeys),
|
||||
new ArrayList<DataWord>(this.storageValues));
|
||||
return contractDetails;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
public String toString() {
|
||||
|
||||
String ret = " Code: " + Hex.toHexString(code) + "\n";
|
||||
ret += " Storage: " + getStorage().toString();
|
||||
|
@ -43,7 +43,7 @@ public class DatabaseImpl implements Database {
|
||||
SystemProperties.CONFIG.databaseDir() + "/");
|
||||
File fileLocation = new File(dbLocation, name);
|
||||
|
||||
if(SystemProperties.CONFIG.databaseReset()) {
|
||||
if (SystemProperties.CONFIG.databaseReset()) {
|
||||
destroyDB(fileLocation);
|
||||
}
|
||||
|
||||
@ -53,12 +53,12 @@ public class DatabaseImpl implements Database {
|
||||
// String stats = DATABASE.getProperty("leveldb.stats");
|
||||
// logger.debug(stats);
|
||||
|
||||
if (logger.isTraceEnabled()){
|
||||
if (logger.isTraceEnabled()) {
|
||||
|
||||
logger.trace("Dump for: {}", fileLocation.toString());
|
||||
DBIterator iter = db.iterator();
|
||||
|
||||
while(iter.hasNext()){
|
||||
while (iter.hasNext()) {
|
||||
byte[] key = iter.peekNext().getKey();
|
||||
byte[] value = iter.peekNext().getValue();
|
||||
|
||||
@ -90,7 +90,7 @@ public class DatabaseImpl implements Database {
|
||||
@Override
|
||||
public void put(byte[] key, byte[] value) {
|
||||
|
||||
if(logger.isDebugEnabled())
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("put: key: [{}], value: [{}]",
|
||||
Hex.toHexString(key),
|
||||
Hex.toHexString(value));
|
||||
@ -99,7 +99,7 @@ public class DatabaseImpl implements Database {
|
||||
|
||||
@Override
|
||||
public void delete(byte[] key) {
|
||||
if(logger.isDebugEnabled())
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("delete: key: [{}]");
|
||||
|
||||
db.delete(key);
|
||||
|
@ -41,7 +41,7 @@ public class RepositoryDummy implements Repository {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger("repository");
|
||||
private Map<ByteArrayWrapper, AccountState> worldState = new HashMap<>();
|
||||
private Map<ByteArrayWrapper, ContractDetails> detailsDB = new HashMap<>() ;
|
||||
private Map<ByteArrayWrapper, ContractDetails> detailsDB = new HashMap<>();
|
||||
|
||||
|
||||
@Override
|
||||
@ -71,21 +71,21 @@ public class RepositoryDummy implements Repository {
|
||||
AccountState accountState = stateCache.get(hash);
|
||||
ContractDetails contractDetails = detailsCache.get(hash);
|
||||
|
||||
if (accountState.isDeleted()){
|
||||
worldState.remove( hash ) ;
|
||||
detailsDB.remove( hash );
|
||||
if (accountState.isDeleted()) {
|
||||
worldState.remove(hash);
|
||||
detailsDB.remove(hash);
|
||||
|
||||
logger.debug("delete: [{}]",
|
||||
Hex.toHexString(hash.getData()));
|
||||
|
||||
} else{
|
||||
} else {
|
||||
|
||||
if (accountState.isDirty() || contractDetails.isDirty()){
|
||||
detailsDB.put( hash, contractDetails);
|
||||
if (accountState.isDirty() || contractDetails.isDirty()) {
|
||||
detailsDB.put(hash, contractDetails);
|
||||
accountState.setStateRoot(contractDetails.getStorageHash());
|
||||
accountState.setCodeHash(sha3(contractDetails.getCode()));
|
||||
worldState.put( hash, accountState);
|
||||
if (logger.isDebugEnabled()){
|
||||
worldState.put(hash, accountState);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("update: [{}],nonce: [{}] balance: [{}] \n [{}]",
|
||||
Hex.toHexString(hash.getData()),
|
||||
accountState.getNonce(),
|
||||
@ -140,7 +140,7 @@ public class RepositoryDummy implements Repository {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Set<ByteArrayWrapper> getFullAddressSet(){
|
||||
public Set<ByteArrayWrapper> getFullAddressSet() {
|
||||
return worldState.keySet();
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ public class RepositoryDummy implements Repository {
|
||||
public void addStorageRow(byte[] addr, DataWord key, DataWord value) {
|
||||
ContractDetails details = getContractDetails(addr);
|
||||
|
||||
if (details == null){
|
||||
if (details == null) {
|
||||
createAccount(addr);
|
||||
details = getContractDetails(addr);
|
||||
}
|
||||
@ -206,13 +206,13 @@ public class RepositoryDummy implements Repository {
|
||||
public void saveCode(byte[] addr, byte[] code) {
|
||||
ContractDetails details = getContractDetails(addr);
|
||||
|
||||
if (details == null){
|
||||
if (details == null) {
|
||||
createAccount(addr);
|
||||
details = getContractDetails(addr);
|
||||
}
|
||||
|
||||
details.setCode(code);
|
||||
detailsDB.put(wrap( addr ), details);
|
||||
detailsDB.put(wrap(addr), details);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,11 +69,11 @@ public class RepositoryImpl implements Repository {
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (this.detailsDB != null){
|
||||
if (this.detailsDB != null) {
|
||||
detailsDB.close();
|
||||
detailsDB = null;
|
||||
}
|
||||
if (this.stateDB != null){
|
||||
if (this.stateDB != null) {
|
||||
stateDB.close();
|
||||
stateDB = null;
|
||||
}
|
||||
@ -93,21 +93,21 @@ public class RepositoryImpl implements Repository {
|
||||
AccountState accountState = stateCache.get(hash);
|
||||
ContractDetails contractDetails = detailsCache.get(hash);
|
||||
|
||||
if (accountState.isDeleted()){
|
||||
if (accountState.isDeleted()) {
|
||||
worldState.delete(hash.getData());
|
||||
detailsDB.delete(hash.getData());
|
||||
|
||||
logger.debug("delete: [{}]",
|
||||
Hex.toHexString(hash.getData()));
|
||||
|
||||
} else{
|
||||
} else {
|
||||
|
||||
if (accountState.isDirty() || contractDetails.isDirty()){
|
||||
if (accountState.isDirty() || contractDetails.isDirty()) {
|
||||
detailsDB.put(hash.getData(), contractDetails.getEncoded());
|
||||
accountState.setStateRoot(contractDetails.getStorageHash());
|
||||
accountState.setCodeHash(sha3(contractDetails.getCode()));
|
||||
worldState.update(hash.getData(), accountState.getEncoded());
|
||||
if (logger.isDebugEnabled()){
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("update: [{}],nonce: [{}] balance: [{}] \n [{}]",
|
||||
Hex.toHexString(hash.getData()),
|
||||
accountState.getNonce(),
|
||||
@ -126,7 +126,7 @@ public class RepositoryImpl implements Repository {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush(){
|
||||
public void flush() {
|
||||
logger.info("flush to disk");
|
||||
worldState.sync();
|
||||
}
|
||||
@ -164,7 +164,9 @@ public class RepositoryImpl implements Repository {
|
||||
if (block.getNumber() == 0 && txNumber == 0)
|
||||
if (CONFIG.dumpCleanOnRestart()) {
|
||||
try {
|
||||
FileUtils.deleteDirectory(CONFIG.dumpDir());} catch (IOException e) {}
|
||||
FileUtils.deleteDirectory(CONFIG.dumpDir());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
String dir = CONFIG.dumpDir() + "/";
|
||||
@ -212,7 +214,7 @@ public class RepositoryImpl implements Repository {
|
||||
}
|
||||
}
|
||||
|
||||
public void dumpTrie(Block block){
|
||||
public void dumpTrie(Block block) {
|
||||
|
||||
if (!(CONFIG.dumpFull() || CONFIG.dumpBlock() == block.getNumber()))
|
||||
return;
|
||||
@ -239,9 +241,11 @@ public class RepositoryImpl implements Repository {
|
||||
logger.error(e.getMessage(), e);
|
||||
} finally {
|
||||
try {
|
||||
if (bw != null)bw.close();
|
||||
if (fw != null)fw.close();
|
||||
} catch (IOException e) {e.printStackTrace();}
|
||||
if (bw != null) bw.close();
|
||||
if (fw != null) fw.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,7 +296,7 @@ public class RepositoryImpl implements Repository {
|
||||
|
||||
ContractDetails details = getContractDetails(addr);
|
||||
|
||||
if (details == null){
|
||||
if (details == null) {
|
||||
createAccount(addr);
|
||||
details = getContractDetails(addr);
|
||||
}
|
||||
@ -316,7 +320,7 @@ public class RepositoryImpl implements Repository {
|
||||
public void saveCode(byte[] addr, byte[] code) {
|
||||
ContractDetails details = getContractDetails(addr);
|
||||
|
||||
if (details == null){
|
||||
if (details == null) {
|
||||
createAccount(addr);
|
||||
details = getContractDetails(addr);
|
||||
}
|
||||
@ -365,8 +369,6 @@ public class RepositoryImpl implements Repository {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void delete(byte[] addr) {
|
||||
worldState.delete(addr);
|
||||
|
@ -32,7 +32,7 @@ public class RepositoryTrack implements Repository {
|
||||
|
||||
Repository repository;
|
||||
|
||||
public RepositoryTrack(){
|
||||
public RepositoryTrack() {
|
||||
this.repository = new RepositoryDummy();
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ public class RepositoryTrack implements Repository {
|
||||
@Override
|
||||
public AccountState createAccount(byte[] addr) {
|
||||
|
||||
logger.trace("createAccount: [{}]", Hex.toHexString(addr)) ;
|
||||
logger.trace("createAccount: [{}]", Hex.toHexString(addr));
|
||||
|
||||
AccountState accountState = new AccountState();
|
||||
cacheAccounts.put(wrap(addr), accountState);
|
||||
@ -59,7 +59,7 @@ public class RepositoryTrack implements Repository {
|
||||
|
||||
AccountState accountState = cacheAccounts.get(wrap(addr));
|
||||
|
||||
if (accountState == null){
|
||||
if (accountState == null) {
|
||||
repository.loadAccount(addr, cacheAccounts, cacheDetails);
|
||||
accountState = cacheAccounts.get(wrap(addr));
|
||||
}
|
||||
@ -83,7 +83,7 @@ public class RepositoryTrack implements Repository {
|
||||
|
||||
ContractDetails contractDetails = cacheDetails.get(wrap(addr));
|
||||
|
||||
if (contractDetails == null){
|
||||
if (contractDetails == null) {
|
||||
repository.loadAccount(addr, cacheAccounts, cacheDetails);
|
||||
contractDetails = cacheDetails.get(wrap(addr));
|
||||
}
|
||||
@ -93,12 +93,12 @@ public class RepositoryTrack implements Repository {
|
||||
|
||||
@Override
|
||||
public void loadAccount(byte[] addr, HashMap<ByteArrayWrapper, AccountState> cacheAccounts,
|
||||
HashMap<ByteArrayWrapper, ContractDetails> cacheDetails){
|
||||
HashMap<ByteArrayWrapper, ContractDetails> cacheDetails) {
|
||||
|
||||
AccountState accountState = this.cacheAccounts.get(wrap(addr));
|
||||
ContractDetails contractDetails = this.cacheDetails.get(wrap(addr));
|
||||
|
||||
if (accountState == null){
|
||||
if (accountState == null) {
|
||||
repository.loadAccount(addr, cacheAccounts, cacheDetails);
|
||||
} else {
|
||||
cacheAccounts.put(wrap(addr), accountState.clone());
|
||||
@ -110,7 +110,7 @@ public class RepositoryTrack implements Repository {
|
||||
@Override
|
||||
public void delete(byte[] addr) {
|
||||
|
||||
logger.trace("delete account: [{}]", Hex.toHexString(addr)) ;
|
||||
logger.trace("delete account: [{}]", Hex.toHexString(addr));
|
||||
getAccountState(addr).setDeleted(true);
|
||||
getContractDetails(addr).setDeleted(true);
|
||||
}
|
||||
@ -165,7 +165,7 @@ public class RepositoryTrack implements Repository {
|
||||
public BigInteger addBalance(byte[] addr, BigInteger value) {
|
||||
|
||||
AccountState accountState = getAccountState(addr);
|
||||
if (accountState == null){
|
||||
if (accountState == null) {
|
||||
accountState = createAccount(addr);
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ public class RepositoryTrack implements Repository {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public Set<ByteArrayWrapper> getFullAddressSet(){
|
||||
public Set<ByteArrayWrapper> getFullAddressSet() {
|
||||
return cacheAccounts.keySet();
|
||||
}
|
||||
|
||||
@ -228,7 +228,7 @@ public class RepositoryTrack implements Repository {
|
||||
|
||||
|
||||
@Override
|
||||
public void flush(){
|
||||
public void flush() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@ -257,13 +257,13 @@ public class RepositoryTrack implements Repository {
|
||||
|
||||
@Override
|
||||
public void updateBatch(HashMap<ByteArrayWrapper, AccountState> accountStates,
|
||||
HashMap<ByteArrayWrapper, ContractDetails> contractDetailes){
|
||||
HashMap<ByteArrayWrapper, ContractDetails> contractDetailes) {
|
||||
|
||||
for (ByteArrayWrapper hash : accountStates.keySet()){
|
||||
for (ByteArrayWrapper hash : accountStates.keySet()) {
|
||||
cacheAccounts.put(hash, accountStates.get(hash));
|
||||
}
|
||||
|
||||
for (ByteArrayWrapper hash : contractDetailes.keySet()){
|
||||
for (ByteArrayWrapper hash : contractDetailes.keySet()) {
|
||||
cacheDetails.put(hash, contractDetailes.get(hash));
|
||||
}
|
||||
}
|
||||
|
@ -30,10 +30,10 @@ public class TrackDatabase implements Database {
|
||||
}
|
||||
|
||||
public void commitTrack() {
|
||||
for(ByteArrayWrapper key : changes.keySet()) {
|
||||
for (ByteArrayWrapper key : changes.keySet()) {
|
||||
db.put(key.getData(), changes.get(key));
|
||||
}
|
||||
for(ByteArrayWrapper key : deletes) {
|
||||
for (ByteArrayWrapper key : deletes) {
|
||||
db.delete(key.getData());
|
||||
}
|
||||
changes = null;
|
||||
@ -57,7 +57,7 @@ public class TrackDatabase implements Database {
|
||||
}
|
||||
|
||||
public byte[] get(byte[] key) {
|
||||
if(trackingChanges) {
|
||||
if (trackingChanges) {
|
||||
ByteArrayWrapper wKey = new ByteArrayWrapper(key);
|
||||
if (deletes.contains(wKey)) return null;
|
||||
if (changes.get(wKey) != null) return changes.get(wKey);
|
||||
@ -65,7 +65,9 @@ public class TrackDatabase implements Database {
|
||||
return db.get(key);
|
||||
}
|
||||
|
||||
/** Delete object (key) from db **/
|
||||
/**
|
||||
* Delete object (key) from db *
|
||||
*/
|
||||
public void delete(byte[] key) {
|
||||
if (trackingChanges) {
|
||||
ByteArrayWrapper wKey = new ByteArrayWrapper(key);
|
||||
@ -76,7 +78,7 @@ public class TrackDatabase implements Database {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(){
|
||||
public void close() {
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
|
@ -16,25 +16,42 @@ public interface Blockchain {
|
||||
public static final byte[] GENESIS_HASH = Genesis.getInstance().getHash();
|
||||
|
||||
public long getSize();
|
||||
|
||||
public void add(Block block);
|
||||
|
||||
public void tryToConnect(Block block);
|
||||
|
||||
public void storeBlock(Block block, List<TransactionReceipt> receipts);
|
||||
|
||||
public Block getBlockByNumber(long blockNr);
|
||||
|
||||
public void setBestBlock(Block block);
|
||||
|
||||
public Block getBestBlock();
|
||||
|
||||
public BlockQueue getQueue();
|
||||
|
||||
public boolean hasParentOnTheChain(Block block);
|
||||
|
||||
public void reset();
|
||||
|
||||
public void close();
|
||||
|
||||
public void updateTotalDifficulty(Block block);
|
||||
|
||||
public BigInteger getTotalDifficulty();
|
||||
|
||||
public void setTotalDifficulty(BigInteger totalDifficulty);
|
||||
|
||||
public byte[] getBestBlockHash();
|
||||
|
||||
public List<byte[]> getListOfHashesStartFrom(byte[] hash, int qty);
|
||||
|
||||
TransactionReceipt getTransactionReceiptByHash(byte[] hash);
|
||||
|
||||
public Block getBlockByHash(byte[] hash);
|
||||
|
||||
public List<Chain> getAltChains();
|
||||
|
||||
public List<Block> getGarbage();
|
||||
}
|
||||
|
@ -24,10 +24,11 @@ public interface Ethereum {
|
||||
|
||||
/**
|
||||
* Find a peer but not this one
|
||||
*
|
||||
* @param excludePeer - peer to exclude
|
||||
* @return online peer if available otherwise null
|
||||
*/
|
||||
public PeerInfo findOnlinePeer(PeerInfo excludePeer) ;
|
||||
public PeerInfo findOnlinePeer(PeerInfo excludePeer);
|
||||
|
||||
/**
|
||||
* Find an online peer but not from excluded list
|
||||
@ -35,7 +36,7 @@ public interface Ethereum {
|
||||
* @param excludePeerSet - peers to exclude
|
||||
* @return online peer if available otherwise null
|
||||
*/
|
||||
public PeerInfo findOnlinePeer(Set<PeerInfo> excludePeerSet) ;
|
||||
public PeerInfo findOnlinePeer(Set<PeerInfo> excludePeerSet);
|
||||
|
||||
/**
|
||||
* @return online peer if available
|
||||
@ -64,9 +65,11 @@ public interface Ethereum {
|
||||
public Set<PeerInfo> getPeers();
|
||||
|
||||
public void startPeerDiscovery();
|
||||
|
||||
public void stopPeerDiscovery();
|
||||
|
||||
public void connect(InetAddress addr, int port);
|
||||
|
||||
public void connect(String ip, int port);
|
||||
|
||||
public Blockchain getBlockchain();
|
||||
|
@ -61,7 +61,7 @@ public class EthereumFactory {
|
||||
|
||||
|
||||
@Bean
|
||||
public DataSourceTransactionManager transactionManager(){
|
||||
public DataSourceTransactionManager transactionManager() {
|
||||
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
|
||||
dataSourceTransactionManager.setDataSource(dataSource());
|
||||
|
||||
@ -69,7 +69,7 @@ public class EthereumFactory {
|
||||
}
|
||||
|
||||
@Bean(name = "dataSource")
|
||||
public DriverManagerDataSource dataSource(){
|
||||
public DriverManagerDataSource dataSource() {
|
||||
|
||||
logger.info("Connecting to the block store");
|
||||
|
||||
@ -99,12 +99,12 @@ public class EthereumFactory {
|
||||
private static EthereumFactory factory;
|
||||
|
||||
|
||||
public static Ethereum createEthereum(){
|
||||
public static Ethereum createEthereum() {
|
||||
|
||||
logger.info("capability eth version: [{}]", EthHandler.VERSION);
|
||||
logger.info("capability shh version: [{}]", ShhHandler.VERSION);
|
||||
|
||||
if (context == null){
|
||||
if (context == null) {
|
||||
context = new AnnotationConfigApplicationContext(EthereumFactory.class);
|
||||
factory = context.getBean(EthereumFactory.class);
|
||||
}
|
||||
|
@ -60,19 +60,22 @@ public class EthereumImpl implements Ethereum {
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init(){
|
||||
public void init() {
|
||||
worldManager.loadBlockchain();
|
||||
if (CONFIG.listenPort() > 0){
|
||||
if (CONFIG.listenPort() > 0) {
|
||||
Executors.newSingleThreadExecutor().submit(
|
||||
new Runnable() { public void run() {
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
peerServer.start(CONFIG.listenPort());
|
||||
}}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a peer but not this one
|
||||
*
|
||||
* @param peer - peer to exclude
|
||||
* @return online peer
|
||||
*/
|
||||
@ -132,7 +135,7 @@ public class EthereumImpl implements Ethereum {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPeerDiscovery(){
|
||||
public void startPeerDiscovery() {
|
||||
worldManager.startPeerDiscovery();
|
||||
}
|
||||
|
||||
@ -179,10 +182,10 @@ public class EthereumImpl implements Ethereum {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PeerClient getDefaultPeer(){
|
||||
public PeerClient getDefaultPeer() {
|
||||
|
||||
PeerClient peer = worldManager.getActivePeer();
|
||||
if (peer == null){
|
||||
if (peer == null) {
|
||||
|
||||
peer = new PeerClient();
|
||||
worldManager.setActivePeer(peer);
|
||||
@ -200,7 +203,7 @@ public class EthereumImpl implements Ethereum {
|
||||
BigInteger gasPrice,
|
||||
BigInteger gas,
|
||||
byte[] recieveAddress,
|
||||
BigInteger value, byte[] data ){
|
||||
BigInteger value, byte[] data) {
|
||||
|
||||
byte[] nonceBytes = ByteUtil.bigIntegerToBytes(nonce);
|
||||
byte[] gasPriceBytes = ByteUtil.bigIntegerToBytes(gasPrice);
|
||||
@ -215,7 +218,7 @@ public class EthereumImpl implements Ethereum {
|
||||
|
||||
|
||||
@Override
|
||||
public Future<Transaction> submitTransaction(Transaction transaction){
|
||||
public Future<Transaction> submitTransaction(Transaction transaction) {
|
||||
|
||||
TransactionTask transactionTask = new TransactionTask(transaction, worldManager);
|
||||
Future<Transaction> future = TransactionExecutor.instance.submitTransaction(transactionTask);
|
||||
@ -225,13 +228,13 @@ public class EthereumImpl implements Ethereum {
|
||||
|
||||
|
||||
@Override
|
||||
public Wallet getWallet(){
|
||||
public Wallet getWallet() {
|
||||
return worldManager.getWallet();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Repository getRepository(){
|
||||
public Repository getRepository() {
|
||||
return worldManager.getRepository();
|
||||
}
|
||||
|
||||
|
@ -172,12 +172,14 @@ public interface Repository {
|
||||
/**
|
||||
* Return to one of the previous snapshots
|
||||
* by moving the root.
|
||||
*
|
||||
* @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();
|
||||
|
@ -15,7 +15,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
* customize ethereum state dumps.
|
||||
*
|
||||
* @author Alon Muroch
|
||||
*
|
||||
*/
|
||||
public class EtherObjectMapper extends ObjectMapper {
|
||||
|
||||
@ -44,7 +43,6 @@ public class EtherObjectMapper extends ObjectMapper {
|
||||
* an ethereum {@link com.fasterxml.jackson.core.PrettyPrinter Pretty Printer} Generator
|
||||
*
|
||||
* @author Alon Muroch
|
||||
*
|
||||
*/
|
||||
public class EtherPrettyPrinter extends DefaultPrettyPrinter {
|
||||
|
||||
|
@ -32,10 +32,10 @@ public class AccountState {
|
||||
|
||||
this.address = address;
|
||||
String balance = accountState.get("balance").toString();
|
||||
String code = (String)accountState.get("code");
|
||||
String code = (String) accountState.get("code");
|
||||
String nonce = accountState.get("nonce").toString();
|
||||
|
||||
JSONObject store = (JSONObject)accountState.get("storage");
|
||||
JSONObject store = (JSONObject) accountState.get("storage");
|
||||
|
||||
this.balance = new BigInteger(balance).toByteArray();
|
||||
|
||||
@ -89,12 +89,12 @@ public class AccountState {
|
||||
return storage;
|
||||
}
|
||||
|
||||
public List<String> compareToReal(org.ethereum.core.AccountState state, ContractDetails details){
|
||||
public List<String> compareToReal(org.ethereum.core.AccountState state, ContractDetails details) {
|
||||
|
||||
List<String> results = new ArrayList<>();
|
||||
|
||||
BigInteger expectedBalance = new BigInteger(1, this.getBalance());
|
||||
if (!state.getBalance().equals(expectedBalance)){
|
||||
if (!state.getBalance().equals(expectedBalance)) {
|
||||
String formatedString = String.format("Account: %s: has unexpected balance, expected balance: %s found balance: %s",
|
||||
Hex.toHexString(this.address), expectedBalance.toString(), state.getBalance().toString());
|
||||
results.add(formatedString);
|
||||
@ -105,13 +105,13 @@ public class AccountState {
|
||||
state.getNonce();
|
||||
this.getNonce();
|
||||
String formatedString = String.format("Account: %s: has unexpected nonce, expected nonce: %s found nonce: %s",
|
||||
Hex.toHexString(this.address), expectedNonce.toString(), state.getNonce().toString() );
|
||||
Hex.toHexString(this.address), expectedNonce.toString(), state.getNonce().toString());
|
||||
results.add(formatedString);
|
||||
}
|
||||
|
||||
if (!Arrays.equals(details.getCode(),this.getCode())) {
|
||||
String formatedString = String.format("Account: %s: has unexpected nonce, expected nonce: %s found nonce: %s",
|
||||
Hex.toHexString(this.address), Hex.toHexString( this.getCode() ), Hex.toHexString(details.getCode()));
|
||||
Hex.toHexString(this.address), Hex.toHexString(this.getCode()), Hex.toHexString(details.getCode()));
|
||||
results.add(formatedString);
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ public class AccountState {
|
||||
Set<DataWord> expectedKeys = this.getStorage().keySet();
|
||||
Set<DataWord> checked = new HashSet<>();
|
||||
|
||||
for (DataWord key : keys){
|
||||
for (DataWord key : keys) {
|
||||
|
||||
DataWord value = details.getStorage().get(key);
|
||||
DataWord expectedValue = this.getStorage().get(key);
|
||||
@ -137,7 +137,7 @@ public class AccountState {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!expectedValue.equals(value)){
|
||||
if (!expectedValue.equals(value)) {
|
||||
|
||||
String formatedString = String.format("Account: %s: has unexpected value, for key: %s , expectedValue: %s real value: %s",
|
||||
Hex.toHexString(this.address), key.toString(),
|
||||
@ -149,8 +149,8 @@ public class AccountState {
|
||||
checked.add(key);
|
||||
}
|
||||
|
||||
for (DataWord key : expectedKeys){
|
||||
if (!checked.contains(key)){
|
||||
for (DataWord key : expectedKeys) {
|
||||
if (!checked.contains(key)) {
|
||||
String formatedString = String.format("Account: %s: doesn't exist expected storage key: %s",
|
||||
Hex.toHexString(this.address), key.toString());
|
||||
results.add(formatedString);
|
||||
|
@ -86,6 +86,7 @@ public class Exec {
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public byte[] getCode() {
|
||||
return code;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ public class Helper {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger("misc");
|
||||
|
||||
public static byte[] parseDataArray(JSONArray valArray){
|
||||
public static byte[] parseDataArray(JSONArray valArray) {
|
||||
|
||||
// value can be:
|
||||
// 1. 324234 number
|
||||
@ -29,34 +29,45 @@ public class Helper {
|
||||
// 3. "239472398472" - big number
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
for (int i = 0; i < valArray.size(); ++i){
|
||||
for (int i = 0; i < valArray.size(); ++i) {
|
||||
|
||||
Object val = valArray.get(i);
|
||||
if (val instanceof String){
|
||||
if (val instanceof String) {
|
||||
|
||||
// Hex num
|
||||
boolean hexVal = Pattern.matches("0[xX][0-9a-fA-F]+", val.toString());
|
||||
if (hexVal){
|
||||
if (hexVal) {
|
||||
String number = ((String) val).substring(2);
|
||||
if (number.length() % 2 == 1) number = "0" + number;
|
||||
byte[] data = Hex.decode(number);
|
||||
try {bos.write(data);} catch (IOException e) { logger.error("should not happen", e);}
|
||||
} else{
|
||||
try {
|
||||
bos.write(data);
|
||||
} catch (IOException e) {
|
||||
logger.error("should not happen", e);
|
||||
}
|
||||
} else {
|
||||
|
||||
// BigInt num
|
||||
boolean isNumeric = Pattern.matches("[0-9a-fA-F]+", val.toString());
|
||||
if (!isNumeric) throw new Error("Wrong test case JSON format");
|
||||
else{
|
||||
else {
|
||||
BigInteger value = new BigInteger(val.toString());
|
||||
try {bos.write(value.toByteArray());} catch (IOException e)
|
||||
{ logger.error("should not happen", e);}
|
||||
try {
|
||||
bos.write(value.toByteArray());
|
||||
} catch (IOException e) {
|
||||
logger.error("should not happen", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (val instanceof Long) {
|
||||
|
||||
// Simple long
|
||||
byte[] data = ByteUtil.bigIntegerToBytes(BigInteger.valueOf((Long)val));
|
||||
try {bos.write(data);} catch (IOException e) {logger.error("should not happen", e);}
|
||||
byte[] data = ByteUtil.bigIntegerToBytes(BigInteger.valueOf((Long) val));
|
||||
try {
|
||||
bos.write(data);
|
||||
} catch (IOException e) {
|
||||
logger.error("should not happen", e);
|
||||
}
|
||||
} else {
|
||||
throw new Error("Wrong test case JSON format");
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ public class JSONReader {
|
||||
|
||||
public static String loadJSON(String filename) {
|
||||
String json = "";
|
||||
if(!SystemProperties.CONFIG.vmTestLoadLocal())
|
||||
if (!SystemProperties.CONFIG.vmTestLoadLocal())
|
||||
json = getFromUrl("https://raw.githubusercontent.com/ethereum/tests/develop/" + filename);
|
||||
return json == "" ? json = getFromLocal(filename) : json;
|
||||
}
|
||||
@ -24,8 +24,9 @@ public class JSONReader {
|
||||
public static String getFromLocal(String filename) {
|
||||
System.out.println("Loading local file: " + filename);
|
||||
try {
|
||||
if(System.getProperty("ETHEREUM_TEST_PATH") == null) {
|
||||
System.out.println("ETHEREUM_TEST_PATH is not passed as a VM argument, please make sure you pass it with the correct path");
|
||||
if (System.getProperty("ETHEREUM_TEST_PATH") == null) {
|
||||
System.out.println("ETHEREUM_TEST_PATH is not passed as a VM argument, please make sure you pass it " +
|
||||
"with the correct path");
|
||||
return "";
|
||||
}
|
||||
System.out.println("From: " + System.getProperty("ETHEREUM_TEST_PATH"));
|
||||
|
@ -18,17 +18,17 @@ public class Logs {
|
||||
|
||||
public Logs(JSONArray jLogs) {
|
||||
|
||||
for (int i = 0; i < jLogs.size(); ++i){
|
||||
for (int i = 0; i < jLogs.size(); ++i) {
|
||||
|
||||
JSONObject jLog = (JSONObject)jLogs.get(i);
|
||||
byte[] address = Hex.decode((String)jLog.get("address"));
|
||||
byte[] data = Hex.decode(((String)jLog.get("data")).substring(2));
|
||||
JSONObject jLog = (JSONObject) jLogs.get(i);
|
||||
byte[] address = Hex.decode((String) jLog.get("address"));
|
||||
byte[] data = Hex.decode(((String) jLog.get("data")).substring(2));
|
||||
|
||||
List<DataWord> topics = new ArrayList<>();
|
||||
|
||||
JSONArray jTopics = (JSONArray)jLog.get("topics");
|
||||
for(Object t: jTopics.toArray()) {
|
||||
byte[] topic = Hex.decode(((String)t));
|
||||
JSONArray jTopics = (JSONArray) jLog.get("topics");
|
||||
for (Object t : jTopics.toArray()) {
|
||||
byte[] topic = Hex.decode(((String) t));
|
||||
topics.add(new DataWord(topic));
|
||||
}
|
||||
|
||||
@ -38,24 +38,24 @@ public class Logs {
|
||||
}
|
||||
|
||||
|
||||
public Iterator<LogInfo> getIterator(){
|
||||
public Iterator<LogInfo> getIterator() {
|
||||
return logs.iterator();
|
||||
}
|
||||
|
||||
|
||||
public List<String> compareToReal(List<LogInfo> logs){
|
||||
public List<String> compareToReal(List<LogInfo> logs) {
|
||||
|
||||
List<String> results = new ArrayList<>();
|
||||
|
||||
int i = 0;
|
||||
for (LogInfo postLog : this.logs){
|
||||
for (LogInfo postLog : this.logs) {
|
||||
|
||||
LogInfo realLog = logs.get(i);
|
||||
|
||||
String postAddress = Hex.toHexString(postLog.getAddress());
|
||||
String realAddress = Hex.toHexString(realLog.getAddress());
|
||||
|
||||
if (!postAddress.equals(realAddress)){
|
||||
if (!postAddress.equals(realAddress)) {
|
||||
|
||||
String formatedString = String.format("Log: %s: has unexpected address, expected address: %s found address: %s",
|
||||
i, postAddress, realAddress);
|
||||
@ -65,7 +65,7 @@ public class Logs {
|
||||
String postData = Hex.toHexString(postLog.getData());
|
||||
String realData = Hex.toHexString(realLog.getData());
|
||||
|
||||
if (!postData.equals(realData)){
|
||||
if (!postData.equals(realData)) {
|
||||
|
||||
String formatedString = String.format("Log: %s: has unexpected data, expected data: %s found data: %s",
|
||||
i, postData, realData);
|
||||
@ -86,11 +86,11 @@ public class Logs {
|
||||
List<DataWord> realTopics = realLog.getTopics();
|
||||
|
||||
int j = 0;
|
||||
for (DataWord postTopic : postTopics){
|
||||
for (DataWord postTopic : postTopics) {
|
||||
|
||||
DataWord realTopic = realTopics.get(j);
|
||||
|
||||
if (!postTopic.equals(realTopic)){
|
||||
if (!postTopic.equals(realTopic)) {
|
||||
|
||||
String formatedString = String.format("Log: %s: has unexpected topic: %s, expected topic: %s found topic: %s",
|
||||
i, j, postTopic, realTopic);
|
||||
|
@ -39,24 +39,24 @@ public class StateTestCase {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public StateTestCase(JSONObject testCaseJSONObj) throws ParseException{
|
||||
public StateTestCase(JSONObject testCaseJSONObj) throws ParseException {
|
||||
|
||||
try {
|
||||
|
||||
JSONObject envJSON = (JSONObject)testCaseJSONObj.get("env");
|
||||
JSONArray logsJSON = (JSONArray)testCaseJSONObj.get("logs");
|
||||
JSONObject envJSON = (JSONObject) testCaseJSONObj.get("env");
|
||||
JSONArray logsJSON = (JSONArray) testCaseJSONObj.get("logs");
|
||||
String outStr = testCaseJSONObj.get("out").toString();
|
||||
JSONObject txJSON = (JSONObject)testCaseJSONObj.get("transaction");
|
||||
JSONObject txJSON = (JSONObject) testCaseJSONObj.get("transaction");
|
||||
|
||||
JSONObject preJSON = (JSONObject)testCaseJSONObj.get("pre");
|
||||
JSONObject postJSON = (JSONObject)testCaseJSONObj.get("post");
|
||||
JSONObject preJSON = (JSONObject) testCaseJSONObj.get("pre");
|
||||
JSONObject postJSON = (JSONObject) testCaseJSONObj.get("post");
|
||||
|
||||
this.env = new Env(envJSON);
|
||||
this.logs = new Logs(logsJSON);
|
||||
this.out = Utils.parseData(outStr);
|
||||
this.transaction = new Transaction(txJSON);
|
||||
|
||||
for (Object key : preJSON.keySet()){
|
||||
for (Object key : preJSON.keySet()) {
|
||||
|
||||
byte[] keyBytes = Hex.decode(key.toString());
|
||||
AccountState accountState =
|
||||
@ -65,7 +65,7 @@ public class StateTestCase {
|
||||
pre.put(new ByteArrayWrapper(keyBytes), accountState);
|
||||
}
|
||||
|
||||
for (Object key : postJSON.keySet()){
|
||||
for (Object key : postJSON.keySet()) {
|
||||
|
||||
byte[] keyBytes = Hex.decode(key.toString());
|
||||
AccountState accountState =
|
||||
|
@ -21,7 +21,7 @@ public class StateTestSuite {
|
||||
|
||||
public StateTestSuite(JSONObject testCaseJSONObj) throws ParseException {
|
||||
|
||||
for (Object key: testCaseJSONObj.keySet()){
|
||||
for (Object key : testCaseJSONObj.keySet()) {
|
||||
|
||||
Object testCaseJSON = testCaseJSONObj.get(key);
|
||||
|
||||
@ -31,7 +31,7 @@ public class StateTestSuite {
|
||||
}
|
||||
}
|
||||
|
||||
public StateTestCase getTestCase(String name){
|
||||
public StateTestCase getTestCase(String name) {
|
||||
|
||||
StateTestCase testCase = testCases.get(name);
|
||||
if (testCase == null) throw new NullPointerException("Test cases doesn't exist: " + name);
|
||||
@ -39,11 +39,9 @@ public class StateTestSuite {
|
||||
return testCase;
|
||||
}
|
||||
|
||||
public Collection<StateTestCase> getAllTests(){
|
||||
public Collection<StateTestCase> getAllTests() {
|
||||
return testCases.values();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -45,45 +45,46 @@ public class TestCase {
|
||||
// "callcreates": { ... }
|
||||
private List<CallCreate> callCreateList = new ArrayList<>();
|
||||
|
||||
public TestCase(String name, JSONObject testCaseJSONObj) throws ParseException{
|
||||
public TestCase(String name, JSONObject testCaseJSONObj) throws ParseException {
|
||||
|
||||
this(testCaseJSONObj);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public TestCase(JSONObject testCaseJSONObj) throws ParseException{
|
||||
public TestCase(JSONObject testCaseJSONObj) throws ParseException {
|
||||
|
||||
try {
|
||||
|
||||
JSONObject envJSON = (JSONObject)testCaseJSONObj.get("env");
|
||||
JSONObject execJSON = (JSONObject)testCaseJSONObj.get("exec");
|
||||
JSONObject preJSON = (JSONObject)testCaseJSONObj.get("pre");
|
||||
JSONObject envJSON = (JSONObject) testCaseJSONObj.get("env");
|
||||
JSONObject execJSON = (JSONObject) testCaseJSONObj.get("exec");
|
||||
JSONObject preJSON = (JSONObject) testCaseJSONObj.get("pre");
|
||||
JSONObject postJSON = new JSONObject();
|
||||
if(testCaseJSONObj.containsKey("post")) // in cases where there is no post dictionary (when testing for exceptions for example)
|
||||
postJSON = (JSONObject)testCaseJSONObj.get("post");
|
||||
if (testCaseJSONObj.containsKey("post")) // in cases where there is no post dictionary (when testing for
|
||||
// exceptions for example)
|
||||
postJSON = (JSONObject) testCaseJSONObj.get("post");
|
||||
JSONArray callCreates = new JSONArray();
|
||||
if(testCaseJSONObj.containsKey("callcreates"))
|
||||
callCreates = (JSONArray)testCaseJSONObj.get("callcreates");
|
||||
if (testCaseJSONObj.containsKey("callcreates"))
|
||||
callCreates = (JSONArray) testCaseJSONObj.get("callcreates");
|
||||
|
||||
JSONArray logsJSON = new JSONArray();
|
||||
if(testCaseJSONObj.containsKey("logs"))
|
||||
logsJSON = (JSONArray)testCaseJSONObj.get("logs");
|
||||
if (testCaseJSONObj.containsKey("logs"))
|
||||
logsJSON = (JSONArray) testCaseJSONObj.get("logs");
|
||||
logs = new Logs(logsJSON);
|
||||
|
||||
String gasString = "0";
|
||||
if(testCaseJSONObj.containsKey("gas"))
|
||||
if (testCaseJSONObj.containsKey("gas"))
|
||||
gasString = testCaseJSONObj.get("gas").toString();
|
||||
this.gas = ByteUtil.bigIntegerToBytes(new BigInteger(gasString));
|
||||
|
||||
String outString = null;
|
||||
if(testCaseJSONObj.containsKey("out"))
|
||||
if (testCaseJSONObj.containsKey("out"))
|
||||
outString = testCaseJSONObj.get("out").toString();
|
||||
if (outString != null && outString.length() > 2)
|
||||
this.out = Hex.decode(outString.substring(2));
|
||||
else
|
||||
this.out = ByteUtil.EMPTY_BYTE_ARRAY;
|
||||
|
||||
for (Object key : preJSON.keySet()){
|
||||
for (Object key : preJSON.keySet()) {
|
||||
|
||||
byte[] keyBytes = Hex.decode(key.toString());
|
||||
AccountState accountState =
|
||||
@ -92,7 +93,7 @@ public class TestCase {
|
||||
pre.put(new ByteArrayWrapper(keyBytes), accountState);
|
||||
}
|
||||
|
||||
for (Object key : postJSON.keySet()){
|
||||
for (Object key : postJSON.keySet()) {
|
||||
|
||||
byte[] keyBytes = Hex.decode(key.toString());
|
||||
AccountState accountState =
|
||||
@ -101,9 +102,9 @@ public class TestCase {
|
||||
post.put(new ByteArrayWrapper(keyBytes), accountState);
|
||||
}
|
||||
|
||||
for (int i = 0; i < callCreates.size(); ++i){
|
||||
for (int i = 0; i < callCreates.size(); ++i) {
|
||||
|
||||
CallCreate cc = new CallCreate((JSONObject)callCreates.get(i));
|
||||
CallCreate cc = new CallCreate((JSONObject) callCreates.get(i));
|
||||
this.callCreateList.add(cc);
|
||||
}
|
||||
|
||||
@ -147,7 +148,7 @@ public class TestCase {
|
||||
return callCreateList;
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
@ -15,11 +15,11 @@ import java.math.BigInteger;
|
||||
* Created on: 19/12/2014 12:22
|
||||
*/
|
||||
|
||||
public class TestProgramInvokeFactory implements ProgramInvokeFactory{
|
||||
public class TestProgramInvokeFactory implements ProgramInvokeFactory {
|
||||
|
||||
Env env;
|
||||
|
||||
TestProgramInvokeFactory(Env env){
|
||||
TestProgramInvokeFactory(Env env) {
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
@ -36,11 +36,11 @@ public class TestProgramInvokeFactory implements ProgramInvokeFactory{
|
||||
}
|
||||
|
||||
|
||||
private ProgramInvoke generalInvoke(Transaction tx, Repository repository){
|
||||
private ProgramInvoke generalInvoke(Transaction tx, Repository repository) {
|
||||
|
||||
/*** ADDRESS op ***/
|
||||
// YP: Get address of currently executing account.
|
||||
byte[] address = tx.isContractCreation() ? tx.getContractAddress(): tx.getReceiveAddress();
|
||||
byte[] address = tx.isContractCreation() ? tx.getContractAddress() : tx.getReceiveAddress();
|
||||
|
||||
/*** ORIGIN op ***/
|
||||
// YP: This is the sender of original transaction; it is never a contract.
|
||||
@ -83,7 +83,7 @@ public class TestProgramInvokeFactory implements ProgramInvokeFactory{
|
||||
byte[] difficulty = env.getCurrentDifficlty();
|
||||
|
||||
/*** GASLIMIT op ***/
|
||||
long gaslimit = ByteUtil.byteArrayToLong( env.getCurrentGasLimit() );
|
||||
long gaslimit = ByteUtil.byteArrayToLong(env.getCurrentGasLimit());
|
||||
|
||||
return new ProgramInvokeImpl(address, origin, caller, balance,
|
||||
gasPrice, gas, callValue, data, lastHash, coinbase,
|
||||
|
@ -53,7 +53,7 @@ public class TestRunner {
|
||||
|
||||
List<String> results = null;
|
||||
logger.info("\n***");
|
||||
logger.info(" Running test case: [" + testCase.getName() + "]") ;
|
||||
logger.info(" Running test case: [" + testCase.getName() + "]");
|
||||
logger.info("***\n");
|
||||
results = new ArrayList<>();
|
||||
|
||||
@ -93,7 +93,7 @@ public class TestRunner {
|
||||
|
||||
Set<ByteArrayWrapper> fullAddressSet = repository.getFullAddressSet();
|
||||
int repoSize = 0;
|
||||
for (ByteArrayWrapper addrWrapped : fullAddressSet){
|
||||
for (ByteArrayWrapper addrWrapped : fullAddressSet) {
|
||||
|
||||
byte[] addr = addrWrapped.getData();
|
||||
|
||||
@ -101,11 +101,11 @@ public class TestRunner {
|
||||
ContractDetails contractDetails = repository.getContractDetails(addr);
|
||||
|
||||
logger.info("{} \n{} \n{}", Hex.toHexString(addr),
|
||||
accountState.toString(), contractDetails.toString() );
|
||||
accountState.toString(), contractDetails.toString());
|
||||
logger.info("");
|
||||
|
||||
AccountState expectedAccountState = testCase.getPost().get(wrap(addr));
|
||||
if (expectedAccountState == null){
|
||||
if (expectedAccountState == null) {
|
||||
String formatedString = String.format("Unexpected account state: address: %s", Hex.toHexString(addr));
|
||||
results.add(formatedString);
|
||||
continue;
|
||||
@ -119,7 +119,7 @@ public class TestRunner {
|
||||
|
||||
int postRepoSize = testCase.getPost().size();
|
||||
|
||||
if (postRepoSize > repoSize){
|
||||
if (postRepoSize > repoSize) {
|
||||
results.add("ERROR: Post repository contains more accounts than executed repository ");
|
||||
}
|
||||
|
||||
@ -129,7 +129,7 @@ public class TestRunner {
|
||||
public List<String> runTestCase(TestCase testCase) {
|
||||
|
||||
logger.info("\n***");
|
||||
logger.info(" Running test case: [" + testCase.getName() + "]") ;
|
||||
logger.info(" Running test case: [" + testCase.getName() + "]");
|
||||
logger.info("***\n");
|
||||
List<String> results = new ArrayList<>();
|
||||
|
||||
@ -161,9 +161,9 @@ public class TestRunner {
|
||||
long gaslimit = new BigInteger(env.getCurrentGasLimit()).longValue();
|
||||
|
||||
// Origin and caller need to exist in order to be able to execute
|
||||
if(repository.getAccountState(origin) == null)
|
||||
if (repository.getAccountState(origin) == null)
|
||||
repository.createAccount(origin);
|
||||
if(repository.getAccountState(caller) == null)
|
||||
if (repository.getAccountState(caller) == null)
|
||||
repository.createAccount(caller);
|
||||
|
||||
ProgramInvoke programInvoke = new ProgramInvokeImpl(address, origin, caller, balance,
|
||||
@ -177,27 +177,24 @@ public class TestRunner {
|
||||
boolean vmDidThrowAnEception = false;
|
||||
RuntimeException e = null;
|
||||
try {
|
||||
while(!program.isStopped())
|
||||
while (!program.isStopped())
|
||||
vm.step(program);
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
} catch (RuntimeException ex) {
|
||||
vmDidThrowAnEception = true;
|
||||
e = ex;
|
||||
}
|
||||
program.saveProgramTraceToFile(testCase.getName());
|
||||
|
||||
if(testCase.getPost().size() == 0) {
|
||||
if(vmDidThrowAnEception != true) {
|
||||
if (testCase.getPost().size() == 0) {
|
||||
if (vmDidThrowAnEception != true) {
|
||||
String output =
|
||||
String.format("VM was expected to throw an exception");
|
||||
logger.info(output);
|
||||
results.add(output);
|
||||
}
|
||||
else
|
||||
} else
|
||||
logger.info("VM did throw an exception: " + e.toString());
|
||||
}
|
||||
else {
|
||||
if(vmDidThrowAnEception) {
|
||||
} else {
|
||||
if (vmDidThrowAnEception) {
|
||||
String output =
|
||||
String.format("VM threw an unexpected exception: " + e.toString());
|
||||
logger.info(output);
|
||||
@ -304,7 +301,7 @@ public class TestRunner {
|
||||
|
||||
Iterator<LogInfo> postLogs = logs.getIterator();
|
||||
int i = 0;
|
||||
while(postLogs.hasNext()) {
|
||||
while (postLogs.hasNext()) {
|
||||
|
||||
LogInfo expectedLogInfo = postLogs.next();
|
||||
|
||||
@ -312,28 +309,27 @@ public class TestRunner {
|
||||
if (logResult.size() > i)
|
||||
foundLogInfo = logResult.get(i);
|
||||
|
||||
if(foundLogInfo == null) {
|
||||
if (foundLogInfo == null) {
|
||||
String output =
|
||||
String.format("Expected log [ %s ]", expectedLogInfo.toString());
|
||||
logger.info(output);
|
||||
results.add(output);
|
||||
}
|
||||
else {
|
||||
if(!Arrays.equals(expectedLogInfo.getAddress(), foundLogInfo.getAddress())) {
|
||||
} else {
|
||||
if (!Arrays.equals(expectedLogInfo.getAddress(), foundLogInfo.getAddress())) {
|
||||
String output =
|
||||
String.format("Expected address [ %s ], found [ %s ]", Hex.toHexString(expectedLogInfo.getAddress()), Hex.toHexString(foundLogInfo.getAddress()));
|
||||
logger.info(output);
|
||||
results.add(output);
|
||||
}
|
||||
|
||||
if(!Arrays.equals(expectedLogInfo.getData(), foundLogInfo.getData())) {
|
||||
if (!Arrays.equals(expectedLogInfo.getData(), foundLogInfo.getData())) {
|
||||
String output =
|
||||
String.format("Expected data [ %s ], found [ %s ]", Hex.toHexString(expectedLogInfo.getData()), Hex.toHexString(foundLogInfo.getData()));
|
||||
logger.info(output);
|
||||
results.add(output);
|
||||
}
|
||||
|
||||
if(!expectedLogInfo.getBloom().equals(foundLogInfo.getBloom())) {
|
||||
if (!expectedLogInfo.getBloom().equals(foundLogInfo.getBloom())) {
|
||||
String output =
|
||||
String.format("Expected bloom [ %s ], found [ %s ]",
|
||||
Hex.toHexString(expectedLogInfo.getBloom().getData()),
|
||||
@ -342,18 +338,18 @@ public class TestRunner {
|
||||
results.add(output);
|
||||
}
|
||||
|
||||
if(expectedLogInfo.getTopics().size() != foundLogInfo.getTopics().size()) {
|
||||
if (expectedLogInfo.getTopics().size() != foundLogInfo.getTopics().size()) {
|
||||
String output =
|
||||
String.format("Expected number of topics [ %d ], found [ %d ]", expectedLogInfo.getTopics().size(), foundLogInfo.getTopics().size());
|
||||
String.format("Expected number of topics [ %d ], found [ %d ]",
|
||||
expectedLogInfo.getTopics().size(), foundLogInfo.getTopics().size());
|
||||
logger.info(output);
|
||||
results.add(output);
|
||||
}
|
||||
else {
|
||||
int j=0;
|
||||
for(DataWord topic: expectedLogInfo.getTopics()) {
|
||||
} else {
|
||||
int j = 0;
|
||||
for (DataWord topic : expectedLogInfo.getTopics()) {
|
||||
byte[] foundTopic = foundLogInfo.getTopics().get(j).getData();
|
||||
|
||||
if(!Arrays.equals(topic.getData(), foundTopic)) {
|
||||
if (!Arrays.equals(topic.getData(), foundTopic)) {
|
||||
String output =
|
||||
String.format("Expected topic [ %s ], found [ %s ]", Hex.toHexString(topic.getData()), Hex.toHexString(foundTopic));
|
||||
logger.info(output);
|
||||
@ -492,7 +488,7 @@ public class TestRunner {
|
||||
}
|
||||
}
|
||||
|
||||
public org.ethereum.core.Transaction createTransaction(Transaction tx){
|
||||
public org.ethereum.core.Transaction createTransaction(Transaction tx) {
|
||||
|
||||
byte[] nonceBytes = ByteUtil.longToBytes(tx.nonce);
|
||||
byte[] gasPriceBytes = ByteUtil.longToBytes(tx.gasPrice);
|
||||
@ -508,7 +504,7 @@ public class TestRunner {
|
||||
return transaction;
|
||||
}
|
||||
|
||||
public RepositoryDummy loadRepository(Map<ByteArrayWrapper, AccountState> pre){
|
||||
public RepositoryDummy loadRepository(Map<ByteArrayWrapper, AccountState> pre) {
|
||||
|
||||
|
||||
RepositoryDummy track = new RepositoryDummy();
|
||||
@ -524,7 +520,7 @@ public class TestRunner {
|
||||
|
||||
track.saveCode(addr, accountState.getCode());
|
||||
|
||||
for (DataWord storageKey : accountState.getStorage().keySet()){
|
||||
for (DataWord storageKey : accountState.getStorage().keySet()) {
|
||||
track.addStorageRow(addr, storageKey, accountState.getStorage().get(storageKey));
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ public class TestSuite {
|
||||
|
||||
public TestSuite(JSONObject testCaseJSONObj) throws ParseException {
|
||||
|
||||
for (Object key: testCaseJSONObj.keySet()){
|
||||
for (Object key : testCaseJSONObj.keySet()) {
|
||||
|
||||
Object testCaseJSON = testCaseJSONObj.get(key);
|
||||
TestCase testCase = new TestCase(key.toString(), (JSONObject) testCaseJSON);
|
||||
@ -26,7 +26,7 @@ public class TestSuite {
|
||||
}
|
||||
}
|
||||
|
||||
public Iterator<TestCase> iterator(){
|
||||
public Iterator<TestCase> iterator() {
|
||||
return testList.iterator();
|
||||
}
|
||||
}
|
||||
|
@ -14,13 +14,13 @@ import org.spongycastle.util.encoders.Hex;
|
||||
public class Utils {
|
||||
|
||||
|
||||
public static byte[] parseData(String data){
|
||||
public static byte[] parseData(String data) {
|
||||
if (data == null) return ByteUtil.EMPTY_BYTE_ARRAY;
|
||||
if (data.startsWith("0x")) data = data.substring(2);
|
||||
return Hex.decode(data);
|
||||
}
|
||||
|
||||
public static long parseLong(String data){
|
||||
public static long parseLong(String data) {
|
||||
return data.equals("") ? 0 : Long.parseLong(data);
|
||||
}
|
||||
|
||||
|
@ -16,11 +16,18 @@ import java.util.Set;
|
||||
public interface EthereumListener {
|
||||
|
||||
public void trace(String output);
|
||||
|
||||
public void onBlock(Block block);
|
||||
|
||||
public void onRecvMessage(Message message);
|
||||
|
||||
public void onSendMessage(Message message);
|
||||
|
||||
public void onPeerDisconnect(String host, long port);
|
||||
|
||||
public void onPendingTransactionsReceived(Set<Transaction> transactions);
|
||||
|
||||
public void onSyncDone();
|
||||
|
||||
public void onNoConnections();
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public class EthereumListenerAdapter implements EthereumListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNoConnections(){
|
||||
public void onNoConnections() {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,8 @@ import java.util.Set;
|
||||
* @author: Roman Mandeleil
|
||||
* Created on: 12/11/2014 08:34
|
||||
*/
|
||||
@Component(value="EthereumListener")
|
||||
public class EthereumListenerWrapper implements EthereumListener{
|
||||
@Component(value = "EthereumListener")
|
||||
public class EthereumListenerWrapper implements EthereumListener {
|
||||
|
||||
EthereumListener listener;
|
||||
|
||||
@ -64,12 +64,12 @@ public class EthereumListenerWrapper implements EthereumListener{
|
||||
|
||||
|
||||
@Override
|
||||
public void onNoConnections(){
|
||||
public void onNoConnections() {
|
||||
if (listener != null)
|
||||
listener.onNoConnections();
|
||||
}
|
||||
|
||||
public void addListener(EthereumListener listener){
|
||||
public void addListener(EthereumListener listener) {
|
||||
if (listener != null)
|
||||
this.listener = listener;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class AdminInfo {
|
||||
return consensus;
|
||||
}
|
||||
|
||||
public void lostConsensus(){
|
||||
public void lostConsensus() {
|
||||
consensus = false;
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public class WorldManager {
|
||||
|
||||
public void addListener(EthereumListener listener) {
|
||||
logger.info("Ethereum listener added");
|
||||
((EthereumListenerWrapper)this.listener).addListener(listener);
|
||||
((EthereumListenerWrapper) this.listener).addListener(listener);
|
||||
}
|
||||
|
||||
public void startPeerDiscovery() {
|
||||
@ -88,7 +88,7 @@ public class WorldManager {
|
||||
peerDiscovery.stop();
|
||||
}
|
||||
|
||||
public void addPendingTransactions(Set<Transaction> transactions){
|
||||
public void addPendingTransactions(Set<Transaction> transactions) {
|
||||
logger.info("Pending transaction list added: size: [{}]", transactions.size());
|
||||
|
||||
if (listener != null)
|
||||
@ -96,15 +96,15 @@ public class WorldManager {
|
||||
pendingTransactions.addAll(transactions);
|
||||
}
|
||||
|
||||
public void clearPendingTransactions(List<Transaction> recivedTransactions){
|
||||
public void clearPendingTransactions(List<Transaction> recivedTransactions) {
|
||||
|
||||
for (Transaction tx : recivedTransactions){
|
||||
for (Transaction tx : recivedTransactions) {
|
||||
logger.info("Clear transaction, hash: [{}]", Hex.toHexString(tx.getHash()));
|
||||
pendingTransactions.remove(tx);
|
||||
}
|
||||
}
|
||||
|
||||
public ChannelManager getChannelManager(){
|
||||
public ChannelManager getChannelManager() {
|
||||
return channelManager;
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ public class WorldManager {
|
||||
return pendingTransactions;
|
||||
}
|
||||
|
||||
public boolean isBlockchainLoading(){
|
||||
public boolean isBlockchainLoading() {
|
||||
return blockchain.getQueue().size() > 2;
|
||||
}
|
||||
|
||||
@ -180,14 +180,14 @@ public class WorldManager {
|
||||
}
|
||||
|
||||
|
||||
if (CONFIG.rootHashStart() != null){
|
||||
if (CONFIG.rootHashStart() != null) {
|
||||
|
||||
// update world state by dummy hash
|
||||
byte[] rootHash = Hex.decode(CONFIG.rootHashStart());
|
||||
logger.info("Loading root hash from property file: [{}]", CONFIG.rootHashStart());
|
||||
this.repository.syncToRoot(rootHash);
|
||||
|
||||
} else{
|
||||
} else {
|
||||
|
||||
// Update world state to latest loaded block from db
|
||||
this.repository.syncToRoot(blockchain.getBestBlock().getStateRoot());
|
||||
@ -202,7 +202,7 @@ public class WorldManager {
|
||||
*/
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
public void reset() {
|
||||
logger.info("Resetting blockchain ");
|
||||
repository.reset();
|
||||
blockchain.reset();
|
||||
|
@ -77,9 +77,9 @@ public class Miner {
|
||||
byte[] testNonce = new byte[32];
|
||||
byte[] concat;
|
||||
|
||||
while(ByteUtil.increment(testNonce) && !stop) {
|
||||
while (ByteUtil.increment(testNonce) && !stop) {
|
||||
|
||||
if (testNonce[31] == 0 && testNonce[30] == 0){
|
||||
if (testNonce[31] == 0 && testNonce[30] == 0) {
|
||||
System.out.println("mining: " + new BigInteger(1, testNonce));
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ public class Miner {
|
||||
sleep();
|
||||
concat = Arrays.concatenate(hash, testNonce);
|
||||
byte[] result = SHA3Helper.sha3(concat);
|
||||
if(FastByteComparisons.compareTo(result, 0, 32, target, 0, 32) < 0) {
|
||||
if (FastByteComparisons.compareTo(result, 0, 32, target, 0, 32) < 0) {
|
||||
newBlock.setNonce(testNonce);
|
||||
return true;
|
||||
}
|
||||
@ -95,11 +95,11 @@ public class Miner {
|
||||
return false; // couldn't find a valid nonce
|
||||
}
|
||||
|
||||
public void stop(){
|
||||
public void stop() {
|
||||
stop = true;
|
||||
}
|
||||
|
||||
private void sleep(){
|
||||
private void sleep() {
|
||||
try {
|
||||
// Thread.sleep(1);
|
||||
Thread.sleep(10);
|
||||
|
@ -27,17 +27,25 @@ public class BlockQueue {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger("blockqueue");
|
||||
|
||||
/** The list of hashes of the heaviest chain on the network,
|
||||
* for which this client doesn't have the blocks yet */
|
||||
/**
|
||||
* 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 */
|
||||
/**
|
||||
* 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 */
|
||||
/**
|
||||
* Highest known total difficulty, representing the heaviest chain on the network
|
||||
*/
|
||||
private BigInteger highestTotalDifficulty;
|
||||
|
||||
/** Last block in the queue to be processed */
|
||||
/**
|
||||
* Last block in the queue to be processed
|
||||
*/
|
||||
private Block lastBlock;
|
||||
|
||||
private Timer timer = new Timer("BlockQueueTimer");
|
||||
@ -61,7 +69,7 @@ public class BlockQueue {
|
||||
return;
|
||||
|
||||
logger.info("BlockQueue size: {}", blockReceivedQueue.size());
|
||||
while(!blockReceivedQueue.isEmpty()){
|
||||
while (!blockReceivedQueue.isEmpty()) {
|
||||
Block block = blockReceivedQueue.poll();
|
||||
|
||||
logger.info("Processing block index: {}", block.getNumber());
|
||||
@ -85,7 +93,7 @@ public class BlockQueue {
|
||||
blockReceivedQueue.addAll(blockList);
|
||||
lastBlock = blockList.get(blockList.size() - 1);
|
||||
|
||||
logger.info("Blocks waiting to be proceed: queue.size: [{}] lastBlock.number: [{}]" ,
|
||||
logger.info("Blocks waiting to be proceed: queue.size: [{}] lastBlock.number: [{}]",
|
||||
blockReceivedQueue.size(),
|
||||
lastBlock.getNumber());
|
||||
}
|
||||
@ -93,14 +101,15 @@ public class BlockQueue {
|
||||
/**
|
||||
* adding single block to the queue usually
|
||||
* a result of a NEW_BLOCK message announce.
|
||||
*
|
||||
* @param block - new block
|
||||
*/
|
||||
public void addBlock(Block block){
|
||||
public void addBlock(Block block) {
|
||||
|
||||
blockReceivedQueue.add(block);
|
||||
lastBlock = block;
|
||||
|
||||
logger.debug("Blocks waiting to be proceed: queue.size: [{}] lastBlock.number: [{}]" ,
|
||||
logger.debug("Blocks waiting to be proceed: queue.size: [{}] lastBlock.number: [{}]",
|
||||
blockReceivedQueue.size(),
|
||||
lastBlock.getNumber());
|
||||
}
|
||||
@ -143,19 +152,19 @@ public class BlockQueue {
|
||||
public void addHash(byte[] hash) {
|
||||
blockHashQueue.addLast(hash);
|
||||
|
||||
if (logger.isTraceEnabled()){
|
||||
logger.trace("Adding hash to a hashQueue: [{}]" , Hex.toHexString(hash));
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Adding hash to a hashQueue: [{}]", Hex.toHexString(hash));
|
||||
}
|
||||
}
|
||||
|
||||
public void returnHashes(List<byte[]> hashes){
|
||||
public void returnHashes(List<byte[]> hashes) {
|
||||
|
||||
ListIterator iterator = hashes.listIterator(hashes.size());
|
||||
while(iterator.hasPrevious())
|
||||
blockHashQueue.addLast((byte[])iterator.previous());
|
||||
while (iterator.hasPrevious())
|
||||
blockHashQueue.addLast((byte[]) iterator.previous());
|
||||
}
|
||||
|
||||
public void addNewBlockHash(byte[] hash){
|
||||
public void addNewBlockHash(byte[] hash) {
|
||||
blockHashQueue.addFirst(hash);
|
||||
}
|
||||
|
||||
@ -175,7 +184,7 @@ public class BlockQueue {
|
||||
|
||||
// a bit ugly but really gives
|
||||
// good result
|
||||
public void logHashQueueSize(){
|
||||
public void logHashQueueSize() {
|
||||
logger.info("Block hashes list size: [{}]", blockHashQueue.size());
|
||||
}
|
||||
|
||||
@ -213,11 +222,11 @@ public class BlockQueue {
|
||||
return blockReceivedQueue.size();
|
||||
}
|
||||
|
||||
public boolean isHashesEmpty(){
|
||||
public boolean isHashesEmpty() {
|
||||
return blockHashQueue.size() == 0;
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
public void clear() {
|
||||
this.blockHashQueue.clear();
|
||||
this.blockReceivedQueue.clear();
|
||||
}
|
||||
|
@ -44,9 +44,10 @@ public class MessageQueue {
|
||||
WorldManager worldManager;
|
||||
boolean hasPing = false;
|
||||
|
||||
public MessageQueue(){}
|
||||
public MessageQueue() {
|
||||
}
|
||||
|
||||
public void activate(ChannelHandlerContext ctx){
|
||||
public void activate(ChannelHandlerContext ctx) {
|
||||
this.ctx = ctx;
|
||||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
public void run() {
|
||||
@ -117,7 +118,7 @@ public class MessageQueue {
|
||||
}
|
||||
}
|
||||
|
||||
public void close(){
|
||||
public void close() {
|
||||
timer.cancel();
|
||||
timer.purge();
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public class Capability implements Comparable<Capability> {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Capability)) return false;
|
||||
|
||||
Capability other = (Capability)obj;
|
||||
Capability other = (Capability) obj;
|
||||
if (this.name == null)
|
||||
return other.name == null;
|
||||
else
|
||||
|
@ -22,6 +22,7 @@ import static org.ethereum.config.SystemProperties.CONFIG;
|
||||
|
||||
/**
|
||||
* This class creates the connection to an remote address using the Netty framework
|
||||
*
|
||||
* @see <a href="http://netty.io">http://netty.io</a>
|
||||
*/
|
||||
@Component
|
||||
|
@ -18,7 +18,9 @@ import org.ethereum.util.Utils;
|
||||
*/
|
||||
public class BlockHashesMessage extends EthMessage {
|
||||
|
||||
/** List of block hashes from the peer ordered from child to parent */
|
||||
/**
|
||||
* List of block hashes from the peer ordered from child to parent
|
||||
*/
|
||||
private List<byte[]> blockHashes;
|
||||
|
||||
public BlockHashesMessage(byte[] payload) {
|
||||
@ -69,7 +71,7 @@ public class BlockHashesMessage extends EthMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EthMessageCodes getCommand(){
|
||||
public EthMessageCodes getCommand() {
|
||||
return EthMessageCodes.BLOCK_HASHES;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ public class BlocksMessage extends EthMessage {
|
||||
super(encoded);
|
||||
}
|
||||
|
||||
public BlocksMessage(List<Block> blocks){
|
||||
public BlocksMessage(List<Block> blocks) {
|
||||
this.blocks = blocks;
|
||||
parsed = true;
|
||||
}
|
||||
@ -45,7 +45,7 @@ public class BlocksMessage extends EthMessage {
|
||||
List<byte[]> encodedElements = new Vector<>();
|
||||
encodedElements.add(RLP.encodeByte(BLOCKS.asByte()));
|
||||
|
||||
for (Block block : blocks){
|
||||
for (Block block : blocks) {
|
||||
encodedElements.add(block.getEncoded());
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ public class BlocksMessage extends EthMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EthMessageCodes getCommand(){
|
||||
public EthMessageCodes getCommand() {
|
||||
return EthMessageCodes.BLOCKS;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
private List<byte[]> sentHashes;
|
||||
private Block lastBlock = Genesis.getInstance();
|
||||
|
||||
public EthHandler(){
|
||||
public EthHandler() {
|
||||
this.peerDiscoveryMode = false;
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
this.msgQueue = msgQueue;
|
||||
}
|
||||
|
||||
public void activate(){
|
||||
public void activate() {
|
||||
logger.info("ETH protocol activated");
|
||||
worldManager.getListener().trace("ETH protocol activated");
|
||||
|
||||
@ -95,7 +95,7 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
}
|
||||
|
||||
|
||||
public boolean isActive(){
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
break;
|
||||
case TRANSACTIONS:
|
||||
msgQueue.receivedMessage(msg);
|
||||
processTransactions((TransactionsMessage)msg);
|
||||
processTransactions((TransactionsMessage) msg);
|
||||
// List<Transaction> txList = transactionsMessage.getTransactions();
|
||||
// for(Transaction tx : txList)
|
||||
// WorldManager.getInstance().getBlockchain().applyTransaction(null,
|
||||
@ -138,7 +138,7 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
break;
|
||||
case GET_BLOCKS:
|
||||
msgQueue.receivedMessage(msg);
|
||||
processGetBlocks( (GetBlocksMessage) msg );
|
||||
processGetBlocks((GetBlocksMessage) msg);
|
||||
break;
|
||||
case BLOCKS:
|
||||
msgQueue.receivedMessage(msg);
|
||||
@ -146,7 +146,7 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
break;
|
||||
case NEW_BLOCK:
|
||||
msgQueue.receivedMessage(msg);
|
||||
procesNewBlock((NewBlockMessage)msg);
|
||||
procesNewBlock((NewBlockMessage) msg);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -157,7 +157,7 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
Set<Transaction> txSet = msg.getTransactions();
|
||||
worldManager.addPendingTransactions(txSet);
|
||||
|
||||
for (Transaction tx : txSet){
|
||||
for (Transaction tx : txSet) {
|
||||
worldManager.getWallet().addTransaction(tx);
|
||||
}
|
||||
}
|
||||
@ -210,10 +210,10 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
BigInteger peerTotalDifficulty = new BigInteger(1, msg.getTotalDifficulty());
|
||||
BigInteger highestKnownTotalDifficulty = blockchain.getTotalDifficulty();
|
||||
|
||||
boolean synced=
|
||||
boolean synced =
|
||||
FastByteComparisons.compareTo(msg.getBestHash(), 0, 32, blockchain.getBestBlockHash(), 0, 32) == 0;
|
||||
|
||||
if ( !synced && (highestKnownTotalDifficulty == null ||
|
||||
if (!synced && (highestKnownTotalDifficulty == null ||
|
||||
peerTotalDifficulty.compareTo(highestKnownTotalDifficulty) > 0)) {
|
||||
|
||||
logger.info(" Their chain is better: total difficulty : {} vs {}",
|
||||
@ -225,7 +225,7 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
chainQueue.setBestHash(msg.getBestHash());
|
||||
syncStatus = SyncSatus.HASH_RETRIEVING;
|
||||
sendGetBlockHashes();
|
||||
} else{
|
||||
} else {
|
||||
logger.info("The peer sync process fully complete");
|
||||
syncStatus = SyncSatus.SYNC_DONE;
|
||||
}
|
||||
@ -249,10 +249,9 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
byte[] foundHash, latestHash = blockchain.getBestBlockHash();
|
||||
while (hashIterator.hasNext()) {
|
||||
foundHash = hashIterator.next();
|
||||
if (FastByteComparisons.compareTo(foundHash, 0, 32, latestHash, 0, 32) != 0){
|
||||
if (FastByteComparisons.compareTo(foundHash, 0, 32, latestHash, 0, 32) != 0) {
|
||||
chainQueue.addHash(foundHash); // store unknown hashes in queue until known hash is found
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
|
||||
logger.trace("Catch up with the hashes until: {[]}", foundHash);
|
||||
// if known hash is found, ignore the rest
|
||||
@ -270,10 +269,10 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
List<Block> blockList = blocksMessage.getBlocks();
|
||||
|
||||
if (!blockList.isEmpty())
|
||||
lastBlock = blockList.get(blockList.size()-1);
|
||||
lastBlock = blockList.get(blockList.size() - 1);
|
||||
|
||||
// check if you got less blocks than you asked
|
||||
if (blockList.size() < sentHashes.size()){
|
||||
if (blockList.size() < sentHashes.size()) {
|
||||
for (int i = 0; i < blockList.size(); ++i)
|
||||
sentHashes.remove(0);
|
||||
|
||||
@ -287,14 +286,14 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
syncStatus = SyncSatus.SYNC_DONE;
|
||||
blockchain.getQueue().addBlocks(blockList);
|
||||
blockchain.getQueue().logHashQueueSize();
|
||||
} else{
|
||||
} else {
|
||||
if (blockList.isEmpty()) return;
|
||||
blockchain.getQueue().addBlocks(blockList);
|
||||
blockchain.getQueue().logHashQueueSize();
|
||||
sendGetBlocks();
|
||||
}
|
||||
|
||||
for (Block block : blockList){
|
||||
for (Block block : blockList) {
|
||||
totalDifficulty.add(block.getCumulativeDifficulty());
|
||||
}
|
||||
}
|
||||
@ -302,9 +301,10 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
|
||||
/**
|
||||
* Processing NEW_BLOCK announce message
|
||||
*
|
||||
* @param newBlockMessage - new block message
|
||||
*/
|
||||
public void procesNewBlock(NewBlockMessage newBlockMessage){
|
||||
public void procesNewBlock(NewBlockMessage newBlockMessage) {
|
||||
|
||||
Block newBlock = newBlockMessage.getBlock();
|
||||
this.lastBlock = newBlock;
|
||||
@ -320,7 +320,7 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
|
||||
// If the GET_BLOCKs stage started add hash to the end of the hash list
|
||||
// then the block will be retrieved in it's turn;
|
||||
if (syncStatus == SyncSatus.BLOCK_RETRIEVING){
|
||||
if (syncStatus == SyncSatus.BLOCK_RETRIEVING) {
|
||||
logger.debug("Sync status BLOCK_RETREIVING add to the end of hash list: block.index: [{}]",
|
||||
newBlock.getNumber());
|
||||
blockchain.getQueue().addNewBlockHash(newBlock.getHash());
|
||||
@ -338,7 +338,7 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
totalDifficulty = new BigInteger(1, newBlockMessage.getDifficulty());
|
||||
}
|
||||
|
||||
private void sendStatus(){
|
||||
private void sendStatus() {
|
||||
byte protocolVersion = EthHandler.VERSION, networkId = EthHandler.NETWORK_ID;
|
||||
BigInteger totalDifficulty = blockchain.getTotalDifficulty();
|
||||
byte[] bestHash = blockchain.getBestBlockHash();
|
||||
@ -357,7 +357,7 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
msgQueue.sendMessage(msg);
|
||||
}
|
||||
|
||||
public void sendNewBlock(Block block){
|
||||
public void sendNewBlock(Block block) {
|
||||
NewBlockMessage msg = new NewBlockMessage(block, block.getDifficulty());
|
||||
msgQueue.sendMessage(msg);
|
||||
}
|
||||
@ -375,7 +375,7 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
// Parallel download blocks based on hashQueue
|
||||
private void sendGetBlocks() {
|
||||
BlockQueue queue = blockchain.getQueue();
|
||||
if (queue.size() > CONFIG.maxBlocksQueued()){
|
||||
if (queue.size() > CONFIG.maxBlocksQueued()) {
|
||||
|
||||
logger.info("postpone asking for blocks: queue: {}", queue.size());
|
||||
getBlocksTimer.schedule(new TimerTask() {
|
||||
@ -420,7 +420,7 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
List<byte[]> hashes = msg.getBlockHashes();
|
||||
|
||||
Vector<Block> blocks = new Vector<>();
|
||||
for (byte[] hash : hashes){
|
||||
for (byte[] hash : hashes) {
|
||||
Block block = blockchain.getBlockByHash(hash);
|
||||
blocks.add(block);
|
||||
}
|
||||
@ -468,37 +468,37 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
|
||||
stopGetTxTimer();
|
||||
}
|
||||
|
||||
public void setSyncStatus(SyncSatus syncStatus){
|
||||
public void setSyncStatus(SyncSatus syncStatus) {
|
||||
this.syncStatus = syncStatus;
|
||||
}
|
||||
|
||||
public SyncSatus getSyncStatus(){
|
||||
public SyncSatus getSyncStatus() {
|
||||
return syncStatus;
|
||||
}
|
||||
|
||||
public void setPeerId(String peerId){
|
||||
public void setPeerId(String peerId) {
|
||||
this.peerId = peerId;
|
||||
}
|
||||
|
||||
public enum SyncSatus{
|
||||
public enum SyncSatus {
|
||||
INIT,
|
||||
HASH_RETRIEVING,
|
||||
BLOCK_RETRIEVING,
|
||||
SYNC_DONE;
|
||||
}
|
||||
|
||||
public void setBestHash(byte[] hash){
|
||||
public void setBestHash(byte[] hash) {
|
||||
blockchain.getQueue().addHash(hash);
|
||||
}
|
||||
|
||||
public void doSync(){
|
||||
public void doSync() {
|
||||
logger.info("Sync force activated");
|
||||
syncStatus = SyncSatus.HASH_RETRIEVING;
|
||||
setBestHash(lastBlock.getHash());
|
||||
sendGetBlockHashes();
|
||||
}
|
||||
|
||||
public StatusMessage getHandshakeStatusMessage(){
|
||||
public StatusMessage getHandshakeStatusMessage() {
|
||||
return handshakeStatusMessage;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,8 @@ import org.ethereum.net.message.Message;
|
||||
|
||||
public abstract class EthMessage extends Message {
|
||||
|
||||
public EthMessage() {}
|
||||
public EthMessage() {
|
||||
}
|
||||
|
||||
public EthMessage(byte[] encoded) {
|
||||
super(encoded);
|
||||
|
@ -15,50 +15,65 @@ public enum EthMessageCodes {
|
||||
|
||||
/* Ethereum protocol */
|
||||
|
||||
/** [0x00, [PROTOCOL_VERSION, NETWORK_ID, TD, BEST_HASH, GENESIS_HASH] <br>
|
||||
/**
|
||||
* [0x00, [PROTOCOL_VERSION, NETWORK_ID, TD, BEST_HASH, GENESIS_HASH] <br>
|
||||
* Inform a peer of it's current ethereum state. This message should be
|
||||
* send after the initial handshake and prior to any ethereum related messages. */
|
||||
* send after the initial handshake and prior to any ethereum related messages.
|
||||
*/
|
||||
STATUS(0x00),
|
||||
|
||||
/** [+0x01] Request the peer to send all transactions
|
||||
* currently in the queue. */
|
||||
/**
|
||||
* [+0x01] Request the peer to send all transactions
|
||||
* currently in the queue.
|
||||
*/
|
||||
GET_TRANSACTIONS(0x01),
|
||||
|
||||
/** [+0x02, [nonce, receiving_address, value, ...], ...] <br>
|
||||
/**
|
||||
* [+0x02, [nonce, receiving_address, value, ...], ...] <br>
|
||||
* Specify (a) transaction(s) that the peer should make sure is included
|
||||
* on its transaction queue. The items in the list (following the first item 0x12)
|
||||
* are transactions in the format described in the main Ethereum specification. */
|
||||
* are transactions in the format described in the main Ethereum specification.
|
||||
*/
|
||||
TRANSACTIONS(0x02),
|
||||
|
||||
/** [+0x03, [hash : B_32, maxBlocks: P]: <br>
|
||||
/**
|
||||
* [+0x03, [hash : B_32, maxBlocks: P]: <br>
|
||||
* Requests a BlockHashes message of at most maxBlocks entries,
|
||||
* of block hashes from the blockchain, starting at the parent of block hash.
|
||||
* Does not require the peer to give maxBlocks hashes -
|
||||
* they could give somewhat fewer. */
|
||||
* they could give somewhat fewer.
|
||||
*/
|
||||
GET_BLOCK_HASHES(0x03),
|
||||
|
||||
/** [+0x04, [hash_0: B_32, hash_1: B_32, ....]: <br>Gives a series of hashes
|
||||
/**
|
||||
* [+0x04, [hash_0: B_32, hash_1: B_32, ....]: <br>Gives a series of hashes
|
||||
* of blocks (each the child of the next). This implies that the blocks
|
||||
* are ordered from youngest to oldest. */
|
||||
* are ordered from youngest to oldest.
|
||||
*/
|
||||
BLOCK_HASHES(0x04),
|
||||
|
||||
/** [+0x05, [hash_0: B_32, hash_1: B_32, ....]: <br>Requests a Blocks message
|
||||
/**
|
||||
* [+0x05, [hash_0: B_32, hash_1: B_32, ....]: <br>Requests a Blocks message
|
||||
* detailing a number of blocks to be sent, each referred to by a hash. <br>
|
||||
* <b>Note:</b> Don't expect that the peer necessarily give you all these blocks
|
||||
* in a single message - you might have to re-request them. */
|
||||
* in a single message - you might have to re-request them.
|
||||
*/
|
||||
GET_BLOCKS(0x05),
|
||||
|
||||
/** [+0x06, [block_header, transaction_list, uncle_list], ...] <br>
|
||||
/**
|
||||
* [+0x06, [block_header, transaction_list, uncle_list], ...] <br>
|
||||
* Specify (a) block(s) that the peer should know about.
|
||||
* The items in the list (following the first item, 0x13)
|
||||
* are blocks in the format described in the main Ethereum specification. */
|
||||
* are blocks in the format described in the main Ethereum specification.
|
||||
*/
|
||||
BLOCKS(0x06),
|
||||
|
||||
/**
|
||||
* [+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
|
||||
* in the main Ethereum specification. */
|
||||
* in the main Ethereum specification.
|
||||
*/
|
||||
NEW_BLOCK(0x07),
|
||||
|
||||
/**
|
||||
@ -70,6 +85,7 @@ public enum EthMessageCodes {
|
||||
private int cmd;
|
||||
|
||||
private static final Map<Integer, EthMessageCodes> intToTypeMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (EthMessageCodes type : EthMessageCodes.values()) {
|
||||
intToTypeMap.put(type.cmd, type);
|
||||
@ -85,13 +101,14 @@ public enum EthMessageCodes {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static boolean inRange(byte code){
|
||||
public static boolean inRange(byte code) {
|
||||
return code >= STATUS.asByte() && code <= PACKET_COUNT.asByte();
|
||||
}
|
||||
|
||||
public static void setOffset(byte offset){
|
||||
public static void setOffset(byte offset) {
|
||||
EthMessageCodes.OFFSET = offset;
|
||||
}
|
||||
|
||||
public byte asByte() {
|
||||
return (byte) (cmd + OFFSET);
|
||||
}
|
||||
|
@ -14,11 +14,15 @@ import org.spongycastle.util.encoders.Hex;
|
||||
*/
|
||||
public class GetBlockHashesMessage extends EthMessage {
|
||||
|
||||
/** The newest block hash from which to start sending older hashes */
|
||||
/**
|
||||
* The newest block hash from which to start sending older hashes
|
||||
*/
|
||||
private byte[] bestHash;
|
||||
|
||||
/** The maximum number of blocks to return.
|
||||
* <b>Note:</b> the peer could return fewer. */
|
||||
/**
|
||||
* The maximum number of blocks to return.
|
||||
* <b>Note:</b> the peer could return fewer.
|
||||
*/
|
||||
private int maxBlocks;
|
||||
|
||||
public GetBlockHashesMessage(byte[] encoded) {
|
||||
@ -51,7 +55,7 @@ public class GetBlockHashesMessage extends EthMessage {
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
if(encoded == null) encode();
|
||||
if (encoded == null) encode();
|
||||
return encoded;
|
||||
}
|
||||
|
||||
@ -72,7 +76,7 @@ public class GetBlockHashesMessage extends EthMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EthMessageCodes getCommand(){
|
||||
public EthMessageCodes getCommand() {
|
||||
return EthMessageCodes.GET_BLOCK_HASHES;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,9 @@ import static org.ethereum.net.eth.EthMessageCodes.GET_BLOCKS;
|
||||
*/
|
||||
public class GetBlocksMessage extends EthMessage {
|
||||
|
||||
/** List of block hashes for which to retrieve the blocks */
|
||||
/**
|
||||
* List of block hashes for which to retrieve the blocks
|
||||
*/
|
||||
private List<byte[]> blockHashes;
|
||||
|
||||
public GetBlocksMessage(byte[] encoded) {
|
||||
@ -67,7 +69,7 @@ public class GetBlocksMessage extends EthMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EthMessageCodes getCommand(){
|
||||
public EthMessageCodes getCommand() {
|
||||
return EthMessageCodes.GET_BLOCKS;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,9 @@ import org.spongycastle.util.encoders.Hex;
|
||||
*/
|
||||
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() {
|
||||
@ -24,7 +26,7 @@ public class GetTransactionsMessage extends EthMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EthMessageCodes getCommand(){
|
||||
public EthMessageCodes getCommand() {
|
||||
return EthMessageCodes.GET_TRANSACTIONS;
|
||||
}
|
||||
|
||||
|
@ -19,14 +19,14 @@ public class NewBlockMessage extends EthMessage {
|
||||
super(encoded);
|
||||
}
|
||||
|
||||
public NewBlockMessage(Block block, byte[] difficulty){
|
||||
public NewBlockMessage(Block block, byte[] difficulty) {
|
||||
this.block = block;
|
||||
this.difficulty = difficulty;
|
||||
encode();
|
||||
}
|
||||
|
||||
private void encode(){
|
||||
byte[] command = RLP.encodeByte( this.getCommand().asByte());
|
||||
private void encode() {
|
||||
byte[] command = RLP.encodeByte(this.getCommand().asByte());
|
||||
byte[] block = this.block.getEncoded();
|
||||
byte[] diff = RLP.encodeElement(this.difficulty);
|
||||
|
||||
@ -44,12 +44,12 @@ public class NewBlockMessage extends EthMessage {
|
||||
parsed = true;
|
||||
}
|
||||
|
||||
public Block getBlock(){
|
||||
public Block getBlock() {
|
||||
if (!parsed) parse();
|
||||
return block;
|
||||
}
|
||||
|
||||
public byte[] getDifficulty(){
|
||||
public byte[] getDifficulty() {
|
||||
if (!parsed) parse();
|
||||
return difficulty;
|
||||
}
|
||||
@ -60,7 +60,7 @@ public class NewBlockMessage extends EthMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EthMessageCodes getCommand(){
|
||||
public EthMessageCodes getCommand() {
|
||||
return EthMessageCodes.NEW_BLOCK;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import org.ethereum.util.RLP;
|
||||
|
||||
/**
|
||||
* Wrapper around an Ethereum Ping message on the network
|
||||
*
|
||||
*/
|
||||
public class PacketCountMessage extends EthMessage {
|
||||
|
||||
@ -23,7 +22,7 @@ public class PacketCountMessage extends EthMessage {
|
||||
}
|
||||
|
||||
private void encode() {
|
||||
this.encoded = RLP.encodeList(new byte[] {EthMessageCodes.STATUS.asByte()} );
|
||||
this.encoded = RLP.encodeList(new byte[]{EthMessageCodes.STATUS.asByte()});
|
||||
}
|
||||
|
||||
|
||||
@ -33,7 +32,7 @@ public class PacketCountMessage extends EthMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EthMessageCodes getCommand(){
|
||||
public EthMessageCodes getCommand() {
|
||||
return EthMessageCodes.PACKET_COUNT;
|
||||
}
|
||||
|
||||
|
@ -18,11 +18,17 @@ public class StatusMessage extends EthMessage {
|
||||
private byte protocolVersion;
|
||||
private byte networkId;
|
||||
|
||||
/** Total difficulty of the best chain as found in block header. */
|
||||
/**
|
||||
* Total difficulty of the best chain as found in block header.
|
||||
*/
|
||||
private byte[] totalDifficulty;
|
||||
/** The hash of the best (i.e. highest TD) known block. */
|
||||
/**
|
||||
* The hash of the best (i.e. highest TD) known block.
|
||||
*/
|
||||
private byte[] bestHash;
|
||||
/** The hash of the Genesis block */
|
||||
/**
|
||||
* The hash of the Genesis block
|
||||
*/
|
||||
private byte[] genesisHash;
|
||||
|
||||
public StatusMessage(byte[] encoded) {
|
||||
@ -101,7 +107,7 @@ public class StatusMessage extends EthMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EthMessageCodes getCommand(){
|
||||
public EthMessageCodes getCommand() {
|
||||
return STATUS;
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ public class TransactionsMessage extends EthMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public EthMessageCodes getCommand(){
|
||||
public EthMessageCodes getCommand() {
|
||||
return EthMessageCodes.TRANSACTIONS;
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ public class TransactionsMessage extends EthMessage {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if(!parsed) parse();
|
||||
if (!parsed) parse();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (Transaction transaction : transactions)
|
||||
sb.append("\n ").append(transaction);
|
||||
|
@ -12,7 +12,8 @@ public abstract class Message {
|
||||
protected byte[] encoded;
|
||||
protected byte code;
|
||||
|
||||
public Message() {}
|
||||
public Message() {
|
||||
}
|
||||
|
||||
public Message(byte[] encoded) {
|
||||
this.encoded = encoded;
|
||||
|
@ -13,7 +13,7 @@ public class MessageFactory {
|
||||
public static Message createMessage(byte[] encoded) {
|
||||
byte code = RLP.getCommandCode(encoded);
|
||||
|
||||
if (P2pMessageCodes.inRange(code)){
|
||||
if (P2pMessageCodes.inRange(code)) {
|
||||
|
||||
P2pMessageCodes receivedCommand = P2pMessageCodes.fromByte(code);
|
||||
switch (receivedCommand) {
|
||||
|
@ -9,39 +9,60 @@ import java.util.Map;
|
||||
*/
|
||||
public enum ReasonCode {
|
||||
|
||||
/** [0x00] Disconnect request by other peer */
|
||||
/**
|
||||
* [0x00] Disconnect request by other peer
|
||||
*/
|
||||
REQUESTED(0x00),
|
||||
|
||||
/** [0x01] */
|
||||
/**
|
||||
* [0x01]
|
||||
*/
|
||||
TCP_ERROR(0x01),
|
||||
|
||||
/** [0x02] Packets can not be parsed */
|
||||
/**
|
||||
* [0x02] Packets can not be parsed
|
||||
*/
|
||||
BAD_PROTOCOL(0x02),
|
||||
|
||||
/** [0x03] This peer is too slow or delivers unreliable data */
|
||||
/**
|
||||
* [0x03] This peer is too slow or delivers unreliable data
|
||||
*/
|
||||
USELESS_PEER(0x03),
|
||||
|
||||
/** [0x04] Already too many connections with other peers */
|
||||
/**
|
||||
* [0x04] Already too many connections with other peers
|
||||
*/
|
||||
TOO_MANY_PEERS(0x04),
|
||||
|
||||
/** [0x05] Already have a running connection with this peer */
|
||||
/**
|
||||
* [0x05] Already have a running connection with this peer
|
||||
*/
|
||||
ALREADY_CONNECTED(0x05),
|
||||
|
||||
/** [0x06] Version of the p2p protocol is not the same as ours */
|
||||
/**
|
||||
* [0x06] Version of the p2p protocol is not the same as ours
|
||||
*/
|
||||
INCOMPATIBLE_PROTOCOL(0x06),
|
||||
|
||||
/** [0x07] Peer identifies itself with the wrong networkId */
|
||||
/**
|
||||
* [0x07] Peer identifies itself with the wrong networkId
|
||||
*/
|
||||
INCOMPATIBLE_NETWORK(0x07),
|
||||
|
||||
/** [0x08] Peer quit voluntarily */
|
||||
/**
|
||||
* [0x08] Peer quit voluntarily
|
||||
*/
|
||||
PEER_QUITING(0x08),
|
||||
|
||||
/** [0xFF] Reason not specified */
|
||||
/**
|
||||
* [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);
|
||||
|
@ -2,7 +2,8 @@ package org.ethereum.net.message;
|
||||
|
||||
public abstract class ShhMessage extends Message {
|
||||
|
||||
public ShhMessage() {}
|
||||
public ShhMessage() {
|
||||
}
|
||||
|
||||
public ShhMessage(byte[] encoded) {
|
||||
super(encoded);
|
||||
|
@ -52,7 +52,7 @@ public class DisconnectMessage extends P2pMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public P2pMessageCodes getCommand(){
|
||||
public P2pMessageCodes getCommand() {
|
||||
return P2pMessageCodes.DISCONNECT;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,9 @@ import org.spongycastle.util.encoders.Hex;
|
||||
*/
|
||||
public class GetPeersMessage extends P2pMessage {
|
||||
|
||||
/** GetPeers message is always a the same single command payload */
|
||||
/**
|
||||
* GetPeers message is always a the same single command payload
|
||||
*/
|
||||
private final static byte[] FIXED_PAYLOAD = Hex.decode("C104");
|
||||
|
||||
@Override
|
||||
@ -18,7 +20,7 @@ public class GetPeersMessage extends P2pMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public P2pMessageCodes getCommand(){
|
||||
public P2pMessageCodes getCommand() {
|
||||
return P2pMessageCodes.GET_PEERS;
|
||||
}
|
||||
|
||||
|
@ -20,16 +20,26 @@ import java.util.List;
|
||||
*/
|
||||
public class HelloMessage extends P2pMessage {
|
||||
|
||||
/** The implemented version of the P2P protocol. */
|
||||
/**
|
||||
* The implemented version of the P2P protocol.
|
||||
*/
|
||||
private byte p2pVersion;
|
||||
/** The underlying client. A user-readable string. */
|
||||
/**
|
||||
* The underlying client. A user-readable string.
|
||||
*/
|
||||
private String clientId;
|
||||
/** A peer-network capability code, readable ASCII and 3 letters.
|
||||
* Currently only "eth", "shh" and "bzz" are known. */
|
||||
/**
|
||||
* 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 */
|
||||
/**
|
||||
* The port on which the peer is listening for an incoming connection
|
||||
*/
|
||||
private int listenPort;
|
||||
/** The identity and public key of the peer */
|
||||
/**
|
||||
* The identity and public key of the peer
|
||||
*/
|
||||
private String peerId;
|
||||
|
||||
public HelloMessage(byte[] encoded) {
|
||||
@ -62,8 +72,8 @@ public class HelloMessage extends P2pMessage {
|
||||
this.capabilities = new ArrayList<>();
|
||||
for (int i = 0; i < capabilityList.size(); i++) {
|
||||
|
||||
RLPElement capId = ((RLPList)capabilityList.get(i)).get(0);
|
||||
RLPElement capVersion = ((RLPList)capabilityList.get(i)).get(1);
|
||||
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];
|
||||
@ -89,7 +99,7 @@ public class HelloMessage extends P2pMessage {
|
||||
Capability capability = this.capabilities.get(i);
|
||||
capabilities[i] = RLP.encodeList(
|
||||
RLP.encodeElement(capability.getName().getBytes()),
|
||||
RLP.encodeElement(new byte[] {capability.getVersion() }));
|
||||
RLP.encodeElement(new byte[]{capability.getVersion()}));
|
||||
}
|
||||
byte[] capabilityList = RLP.encodeList(capabilities);
|
||||
byte[] peerPort = RLP.encodeInt(this.listenPort);
|
||||
@ -131,7 +141,7 @@ public class HelloMessage extends P2pMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public P2pMessageCodes getCommand(){
|
||||
public P2pMessageCodes getCommand() {
|
||||
return P2pMessageCodes.HELLO;
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
||||
startTimers();
|
||||
}
|
||||
|
||||
public void activate(){
|
||||
public void activate() {
|
||||
|
||||
// logger.info("Incoming connection from: {}", ch.remoteAddress().toString());
|
||||
|
||||
@ -100,7 +100,7 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
||||
worldManager.getListener().trace("P2P protocol activated");
|
||||
}
|
||||
|
||||
public boolean isActive(){
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
||||
if (P2pMessageCodes.inRange(msg.getCommand().asByte()))
|
||||
logger.info("P2PHandler invoke: [{}]", msg.getCommand());
|
||||
|
||||
worldManager.getListener().trace(String.format( "P2PHandler invoke: [%s]", msg.getCommand()));
|
||||
worldManager.getListener().trace(String.format("P2PHandler invoke: [%s]", msg.getCommand()));
|
||||
|
||||
switch (msg.getCommand()) {
|
||||
case HELLO:
|
||||
@ -139,7 +139,7 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
||||
processPeers(ctx, (PeersMessage) msg);
|
||||
|
||||
if (peerDiscoveryMode &&
|
||||
!handshakeHelloMessage.getCapabilities().contains(Capability.ETH)){
|
||||
!handshakeHelloMessage.getCapabilities().contains(Capability.ETH)) {
|
||||
msgQueue.sendMessage(new DisconnectMessage(ReasonCode.REQUESTED));
|
||||
killTimers();
|
||||
ctx.close().sync();
|
||||
@ -172,21 +172,21 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
||||
worldManager.getPeerDiscovery().addPeers(peersMessage.getPeers());
|
||||
}
|
||||
|
||||
private void sendGetPeers(){
|
||||
msgQueue.sendMessage( StaticMessages.GET_PEERS_MESSAGE );
|
||||
private void sendGetPeers() {
|
||||
msgQueue.sendMessage(StaticMessages.GET_PEERS_MESSAGE);
|
||||
}
|
||||
|
||||
private void sendPeers() {
|
||||
|
||||
Set<PeerInfo> peers = worldManager.getPeerDiscovery().getPeers();
|
||||
|
||||
if (lastPeersSent != null && peers.equals(lastPeersSent)){
|
||||
if (lastPeersSent != null && peers.equals(lastPeersSent)) {
|
||||
logger.info("No new peers discovered don't answer for GetPeers");
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Peer> peerSet = new HashSet<>();
|
||||
for (PeerInfo peer : peers){
|
||||
for (PeerInfo peer : peers) {
|
||||
new Peer(peer.getAddress(), peer.getPort(), peer.getPeerId());
|
||||
}
|
||||
|
||||
@ -205,20 +205,19 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
||||
List<Capability> capInCommon = new ArrayList<>();
|
||||
for (Capability capability : msg.getCapabilities()) {
|
||||
if (HELLO_MESSAGE.getCapabilities().contains(capability)) {
|
||||
if (capability.getName().equals(Capability.ETH)){
|
||||
if (capability.getName().equals(Capability.ETH)) {
|
||||
|
||||
// Activate EthHandler for this peer
|
||||
EthHandler ethHandler =
|
||||
(EthHandler)ctx.pipeline().get(Capability.ETH);
|
||||
(EthHandler) ctx.pipeline().get(Capability.ETH);
|
||||
|
||||
ethHandler.setPeerId(msg.getPeerId());
|
||||
ethHandler.activate();
|
||||
}
|
||||
else if (capability.getName().equals(Capability.SHH)){
|
||||
} else if (capability.getName().equals(Capability.SHH)) {
|
||||
|
||||
// Activate ShhHandler for this peer
|
||||
ShhHandler shhHandler =
|
||||
(ShhHandler)ctx.pipeline().get(Capability.SHH);
|
||||
(ShhHandler) ctx.pipeline().get(Capability.SHH);
|
||||
shhHandler.activate();
|
||||
}
|
||||
capInCommon.add(capability);
|
||||
@ -239,15 +238,16 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
||||
|
||||
/**
|
||||
* submit transaction to the network
|
||||
*
|
||||
* @param tx - fresh transaction object
|
||||
*/
|
||||
public void sendTransaction(Transaction tx ){
|
||||
public void sendTransaction(Transaction tx) {
|
||||
|
||||
TransactionsMessage msg = new TransactionsMessage(tx);
|
||||
msgQueue.sendMessage(msg);
|
||||
}
|
||||
|
||||
public void sendNewBlock(Block block ){
|
||||
public void sendNewBlock(Block block) {
|
||||
|
||||
NewBlockMessage msg = new NewBlockMessage(block, block.getDifficulty());
|
||||
msgQueue.sendMessage(msg);
|
||||
@ -296,7 +296,7 @@ public class P2pHandler extends SimpleChannelInboundHandler<P2pMessage> {
|
||||
*/
|
||||
}
|
||||
|
||||
public void killTimers(){
|
||||
public void killTimers() {
|
||||
timer.cancel();
|
||||
timer.purge();
|
||||
msgQueue.close();
|
||||
|
@ -5,7 +5,8 @@ import org.ethereum.net.p2p.P2pMessageCodes;
|
||||
|
||||
public abstract class P2pMessage extends Message {
|
||||
|
||||
public P2pMessage() {}
|
||||
public P2pMessage() {
|
||||
}
|
||||
|
||||
public P2pMessage(byte[] encoded) {
|
||||
super(encoded);
|
||||
|
@ -8,6 +8,7 @@ import java.util.Map;
|
||||
* <br>
|
||||
* The codes for these commands are the first byte in every packet.
|
||||
* ÐΞV
|
||||
*
|
||||
* @see <a href="https://github.com/ethereum/wiki/wiki/%C3%90%CE%9EVp2p-Wire-Protocol">
|
||||
* https://github.com/ethereum/wiki/wiki/ÐΞVp2p-Wire-Protocol</a>
|
||||
*/
|
||||
@ -15,33 +16,45 @@ public enum P2pMessageCodes {
|
||||
|
||||
/* P2P protocol */
|
||||
|
||||
/** [0x00, P2P_VERSION, CLIEND_ID, CAPS, LISTEN_PORT, CLIENT_ID] <br>
|
||||
/**
|
||||
* [0x00, P2P_VERSION, CLIEND_ID, CAPS, LISTEN_PORT, CLIENT_ID] <br>
|
||||
* First packet sent over the connection, and sent once by both sides.
|
||||
* No other messages may be sent until a Hello is received. */
|
||||
* No other messages may be sent until a Hello is received.
|
||||
*/
|
||||
HELLO(0x00),
|
||||
|
||||
/** [0x01, REASON] <br>Inform the peer that a disconnection is imminent;
|
||||
/**
|
||||
* [0x01, REASON] <br>Inform the peer that a disconnection is imminent;
|
||||
* if received, a peer should disconnect immediately. When sending,
|
||||
* well-behaved hosts give their peers a fighting chance (read: wait 2 seconds)
|
||||
* to disconnect to before disconnecting themselves. */
|
||||
* to disconnect to before disconnecting themselves.
|
||||
*/
|
||||
DISCONNECT(0x01),
|
||||
|
||||
/** [0x02] <br>Requests an immediate reply of Pong from the peer. */
|
||||
/**
|
||||
* [0x02] <br>Requests an immediate reply of Pong from the peer.
|
||||
*/
|
||||
PING(0x02),
|
||||
|
||||
/** [0x03] <br>Reply to peer's Ping packet. */
|
||||
/**
|
||||
* [0x03] <br>Reply to peer's Ping packet.
|
||||
*/
|
||||
PONG(0x03),
|
||||
|
||||
/** [0x04] <br>Request the peer to enumerate some known peers
|
||||
* for us to connect to. This should include the peer itself. */
|
||||
/**
|
||||
* [0x04] <br>Request the peer to enumerate some known peers
|
||||
* for us to connect to. This should include the peer itself.
|
||||
*/
|
||||
GET_PEERS(0x04),
|
||||
|
||||
/** [0x05, [IP1, Port1, Id1], [IP2, Port2, Id2], ... ] <br>
|
||||
/**
|
||||
* [0x05, [IP1, Port1, Id1], [IP2, Port2, Id2], ... ] <br>
|
||||
* Specifies a number of known peers. IP is a 4-byte array 'ABCD'
|
||||
* that should be interpreted as the IP address A.B.C.D.
|
||||
* Port is a 2-byte array that should be interpreted as a
|
||||
* 16-bit big-endian integer. Id is the 512-bit hash that acts
|
||||
* as the unique identifier of the node. */
|
||||
* as the unique identifier of the node.
|
||||
*/
|
||||
PEERS(0x05),
|
||||
|
||||
|
||||
@ -54,6 +67,7 @@ public enum P2pMessageCodes {
|
||||
private int cmd;
|
||||
|
||||
private static final Map<Integer, P2pMessageCodes> intToTypeMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (P2pMessageCodes type : P2pMessageCodes.values()) {
|
||||
intToTypeMap.put(type.cmd, type);
|
||||
@ -69,7 +83,7 @@ public enum P2pMessageCodes {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static boolean inRange(byte code){
|
||||
public static boolean inRange(byte code) {
|
||||
|
||||
if (code >= HELLO.asByte() && code <= USER.asByte())
|
||||
return true;
|
||||
|
@ -47,7 +47,7 @@ public class Peer {
|
||||
byte[] port = RLP.encodeInt(this.port);
|
||||
byte[] peerId = RLP.encodeElement(Hex.decode(this.peerId));
|
||||
byte[][] encodedCaps = new byte[this.capabilities.size()][];
|
||||
for (int i = 0; i < this.capabilities.size()*2; i++) {
|
||||
for (int i = 0; i < this.capabilities.size() * 2; i++) {
|
||||
encodedCaps[i] = RLP.encodeString(this.capabilities.get(i).getName());
|
||||
encodedCaps[i] = RLP.encodeByte(this.capabilities.get(i).getVersion());
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ public class PeersMessage extends P2pMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public P2pMessageCodes getCommand(){
|
||||
public P2pMessageCodes getCommand() {
|
||||
return P2pMessageCodes.PEERS;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,9 @@ import org.spongycastle.util.encoders.Hex;
|
||||
*/
|
||||
public class PingMessage extends P2pMessage {
|
||||
|
||||
/** Ping message is always a the same single command payload */
|
||||
/**
|
||||
* Ping message is always a the same single command payload
|
||||
*/
|
||||
private static byte[] FIXED_PAYLOAD = Hex.decode("C102");
|
||||
|
||||
public byte[] getEncoded() {
|
||||
@ -22,7 +24,7 @@ public class PingMessage extends P2pMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public P2pMessageCodes getCommand(){
|
||||
public P2pMessageCodes getCommand() {
|
||||
return P2pMessageCodes.PING;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,9 @@ import org.spongycastle.util.encoders.Hex;
|
||||
*/
|
||||
public class PongMessage extends P2pMessage {
|
||||
|
||||
/** Pong message is always a the same single command payload */
|
||||
/**
|
||||
* Pong message is always a the same single command payload
|
||||
*/
|
||||
private static byte[] FIXED_PAYLOAD = Hex.decode("C103");
|
||||
|
||||
@Override
|
||||
@ -24,7 +26,7 @@ public class PongMessage extends P2pMessage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public P2pMessageCodes getCommand(){
|
||||
public P2pMessageCodes getCommand() {
|
||||
return P2pMessageCodes.PONG;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ import static org.ethereum.config.SystemProperties.CONFIG;
|
||||
|
||||
/**
|
||||
* This class creates the connection to an remote address using the Netty framework
|
||||
*
|
||||
* @see <a href="http://netty.io">http://netty.io</a>
|
||||
*/
|
||||
@Component
|
||||
@ -93,7 +94,7 @@ public class DiscoveryChannel {
|
||||
|
||||
b.handler(
|
||||
|
||||
new ChannelInitializer<NioSocketChannel>(){
|
||||
new ChannelInitializer<NioSocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(NioSocketChannel ch) throws Exception {
|
||||
|
||||
@ -128,7 +129,7 @@ public class DiscoveryChannel {
|
||||
} finally {
|
||||
workerGroup.shutdownGracefully();
|
||||
|
||||
if (!peerDiscoveryMode){
|
||||
if (!peerDiscoveryMode) {
|
||||
// EthereumListener listener = WorldManager.getInstance().getListener();
|
||||
// listener.onPeerDisconnect(host, port);
|
||||
}
|
||||
@ -136,12 +137,11 @@ public class DiscoveryChannel {
|
||||
}
|
||||
}
|
||||
|
||||
public HelloMessage getHelloHandshake(){
|
||||
public HelloMessage getHelloHandshake() {
|
||||
return p2pHandler.getHandshakeHelloMessage();
|
||||
}
|
||||
|
||||
public StatusMessage getStatusHandshake()
|
||||
{
|
||||
public StatusMessage getStatusHandshake() {
|
||||
return ethHandler.getHandshakeStatusMessage();
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ public class PeerDiscovery {
|
||||
for (final Peer newPeer : newPeers) {
|
||||
PeerInfo peerInfo =
|
||||
new PeerInfo(newPeer.getAddress(), newPeer.getPort(), newPeer.getPeerId());
|
||||
if (started.get() && !peers.contains(peerInfo )){
|
||||
if (started.get() && !peers.contains(peerInfo)) {
|
||||
startWorker(peerInfo);
|
||||
}
|
||||
peers.add(peerInfo);
|
||||
@ -115,12 +115,12 @@ public class PeerDiscovery {
|
||||
executorPool.execute(workerThread);
|
||||
}
|
||||
|
||||
public List<PeerInfo> parsePeerDiscoveryIpList(final String peerDiscoveryIpList){
|
||||
public List<PeerInfo> parsePeerDiscoveryIpList(final String peerDiscoveryIpList) {
|
||||
|
||||
final List<String> ipList = Arrays.asList( peerDiscoveryIpList.split(",") );
|
||||
final List<String> ipList = Arrays.asList(peerDiscoveryIpList.split(","));
|
||||
final List<PeerInfo> peers = new ArrayList<>();
|
||||
|
||||
for (String ip : ipList){
|
||||
for (String ip : ipList) {
|
||||
String[] addr = ip.trim().split(":");
|
||||
String ip_trim = addr[0];
|
||||
String port_trim = addr[1];
|
||||
|
@ -30,7 +30,7 @@ public class WorkerThread implements Runnable {
|
||||
public WorkerThread() {
|
||||
}
|
||||
|
||||
public void init(PeerInfo peer, ThreadPoolExecutor poolExecutor){
|
||||
public void init(PeerInfo peer, ThreadPoolExecutor poolExecutor) {
|
||||
this.peerInfo = peer;
|
||||
this.poolExecutor = poolExecutor;
|
||||
}
|
||||
@ -54,7 +54,7 @@ public class WorkerThread implements Runnable {
|
||||
peerInfo.setOnline(true);
|
||||
|
||||
peerInfo.setHandshakeHelloMessage(discoveryChannel.getHelloHandshake());
|
||||
peerInfo.setStatusMessage( discoveryChannel.getStatusHandshake() );
|
||||
peerInfo.setStatusMessage(discoveryChannel.getStatusHandshake());
|
||||
|
||||
logger.info("Peer is online: [{}] ", peerInfo);
|
||||
|
||||
@ -72,7 +72,7 @@ public class WorkerThread implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private void sleep(long milliseconds){
|
||||
private void sleep(long milliseconds) {
|
||||
|
||||
try {
|
||||
Thread.sleep(milliseconds);
|
||||
|
@ -52,7 +52,7 @@ public class Channel {
|
||||
public Channel() {
|
||||
}
|
||||
|
||||
public void init(){
|
||||
public void init() {
|
||||
p2pHandler.setMsgQueue(msgQueue);
|
||||
ethHandler.setMsgQueue(msgQueue);
|
||||
shhHandler.setMsgQueue(msgQueue);
|
||||
@ -80,27 +80,27 @@ public class Channel {
|
||||
return messageEncoder;
|
||||
}
|
||||
|
||||
public void sendTransaction(Transaction tx){
|
||||
public void sendTransaction(Transaction tx) {
|
||||
ethHandler.sendTransaction(tx);
|
||||
}
|
||||
|
||||
public void sendNewBlock(Block block){
|
||||
public void sendNewBlock(Block block) {
|
||||
|
||||
// 1. check by best block send or not to send
|
||||
ethHandler.sendNewBlock(block);
|
||||
|
||||
}
|
||||
|
||||
public boolean isSync(){
|
||||
public boolean isSync() {
|
||||
return ethHandler.getSyncStatus() == EthHandler.SyncSatus.SYNC_DONE;
|
||||
}
|
||||
|
||||
|
||||
public BigInteger getTotalDifficulty(){
|
||||
public BigInteger getTotalDifficulty() {
|
||||
return ethHandler.getTotalDifficulty();
|
||||
}
|
||||
|
||||
public void ethSync(){
|
||||
public void ethSync() {
|
||||
ethHandler.doSync();
|
||||
}
|
||||
|
||||
|
@ -36,63 +36,63 @@ public class ChannelManager {
|
||||
|
||||
|
||||
@PostConstruct
|
||||
public void init(){
|
||||
public void init() {
|
||||
scheduleChannelCollector();
|
||||
}
|
||||
|
||||
public void recvTransaction(){
|
||||
public void recvTransaction() {
|
||||
// ???
|
||||
}
|
||||
|
||||
|
||||
public void recvBlock(){ // todo:
|
||||
public void recvBlock() { // todo:
|
||||
// 1. Check in the cache if the hash exist
|
||||
// 2. Exist: go and send it to the queue
|
||||
}
|
||||
|
||||
public void sendTransaction(Transaction tx){
|
||||
for (Channel channel : channels){
|
||||
public void sendTransaction(Transaction tx) {
|
||||
for (Channel channel : channels) {
|
||||
channel.sendTransaction(tx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void sendNewBlock(Block block){
|
||||
public void sendNewBlock(Block block) {
|
||||
// 1. Go over all channels and send the block
|
||||
for (Channel channel : channels){
|
||||
for (Channel channel : channels) {
|
||||
channel.sendNewBlock(block);
|
||||
}
|
||||
}
|
||||
|
||||
public void addChannel(Channel channel){
|
||||
synchronized (channels){
|
||||
public void addChannel(Channel channel) {
|
||||
synchronized (channels) {
|
||||
channels.add(channel);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAllSync(){
|
||||
public boolean isAllSync() {
|
||||
|
||||
boolean result = true;
|
||||
for (Channel channel : channels){
|
||||
for (Channel channel : channels) {
|
||||
result &= channel.isSync();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void scheduleChannelCollector(){
|
||||
public void scheduleChannelCollector() {
|
||||
inactivesCollector.scheduleAtFixedRate(new TimerTask() {
|
||||
public void run() {
|
||||
Iterator<Channel> iter = channels.iterator();
|
||||
while(iter.hasNext()){
|
||||
while (iter.hasNext()) {
|
||||
Channel channel = iter.next();
|
||||
if(!channel.p2pHandler.isActive()){
|
||||
if (!channel.p2pHandler.isActive()) {
|
||||
iter.remove();
|
||||
logger.info("Channel removed: {}", channel.p2pHandler.getHandshakeHelloMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (channels.size() == 0){
|
||||
if (channels.size() == 0) {
|
||||
worldManager.getListener().onNoConnections();
|
||||
}
|
||||
}
|
||||
@ -102,10 +102,10 @@ public class ChannelManager {
|
||||
public void ethSync() {
|
||||
|
||||
Channel bestChannel = channels.get(0);
|
||||
for (Channel channel : channels){
|
||||
for (Channel channel : channels) {
|
||||
|
||||
if (bestChannel.getTotalDifficulty().
|
||||
compareTo(channel.getTotalDifficulty()) < 0 ){
|
||||
compareTo(channel.getTotalDifficulty()) < 0) {
|
||||
bestChannel = channel;
|
||||
}
|
||||
}
|
||||
|
@ -14,8 +14,6 @@ import org.springframework.stereotype.Component;
|
||||
* Process the messages between peers with 'shh' capability on the network.
|
||||
*
|
||||
* Peers with 'shh' capability can send/receive:
|
||||
*
|
||||
*
|
||||
*/
|
||||
@Component
|
||||
@Scope("prototype")
|
||||
@ -31,7 +29,7 @@ public class ShhHandler extends SimpleChannelInboundHandler<ShhMessage> {
|
||||
@Autowired
|
||||
WorldManager worldManager;
|
||||
|
||||
public ShhHandler(){
|
||||
public ShhHandler() {
|
||||
}
|
||||
|
||||
public ShhHandler(MessageQueue msgQueue) {
|
||||
@ -46,7 +44,7 @@ public class ShhHandler extends SimpleChannelInboundHandler<ShhMessage> {
|
||||
if (ShhMessageCodes.inRange(msg.getCommand().asByte()))
|
||||
logger.info("ShhHandler invoke: [{}]", msg.getCommand());
|
||||
|
||||
worldManager.getListener().trace(String.format( "ShhHandler invoke: [%s]", msg.getCommand()));
|
||||
worldManager.getListener().trace(String.format("ShhHandler invoke: [%s]", msg.getCommand()));
|
||||
|
||||
switch (msg.getCommand()) {
|
||||
case STATUS:
|
||||
@ -77,7 +75,7 @@ public class ShhHandler extends SimpleChannelInboundHandler<ShhMessage> {
|
||||
logger.debug("handlerRemoved: ... ");
|
||||
}
|
||||
|
||||
public void activate(){
|
||||
public void activate() {
|
||||
logger.info("SHH protocol activated");
|
||||
worldManager.getListener().trace("SHH protocol activated");
|
||||
this.active = true;
|
||||
|
@ -4,7 +4,8 @@ import org.ethereum.net.message.Message;
|
||||
|
||||
public abstract class ShhMessage extends Message {
|
||||
|
||||
public ShhMessage() {}
|
||||
public ShhMessage() {
|
||||
}
|
||||
|
||||
public ShhMessage(byte[] encoded) {
|
||||
super(encoded);
|
||||
|
@ -15,25 +15,36 @@ public enum ShhMessageCodes {
|
||||
|
||||
/* Whisper Protocol */
|
||||
|
||||
/** [+0x00] */
|
||||
/**
|
||||
* [+0x00]
|
||||
*/
|
||||
STATUS(0x00),
|
||||
|
||||
/** [+0x01] */
|
||||
/**
|
||||
* [+0x01]
|
||||
*/
|
||||
MESSAGE(0x01),
|
||||
|
||||
/** [+0x02] */
|
||||
/**
|
||||
* [+0x02]
|
||||
*/
|
||||
ADD_FILTER(0x02),
|
||||
|
||||
/** [+0x03] */
|
||||
/**
|
||||
* [+0x03]
|
||||
*/
|
||||
REMOVE_FILTER(0x03),
|
||||
|
||||
/** [+0x04] */
|
||||
/**
|
||||
* [+0x04]
|
||||
*/
|
||||
PACKET_COUNT(0x04);
|
||||
|
||||
static byte OFFSET = 0;
|
||||
private int cmd;
|
||||
|
||||
private static final Map<Integer, ShhMessageCodes> intToTypeMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (ShhMessageCodes type : ShhMessageCodes.values()) {
|
||||
intToTypeMap.put(type.cmd, type);
|
||||
@ -49,11 +60,11 @@ public enum ShhMessageCodes {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static void setOffset(byte offset){
|
||||
public static void setOffset(byte offset) {
|
||||
ShhMessageCodes.OFFSET = offset;
|
||||
}
|
||||
|
||||
public static boolean inRange(byte code){
|
||||
public static boolean inRange(byte code) {
|
||||
|
||||
if (code >= STATUS.asByte() && code <= PACKET_COUNT.asByte())
|
||||
return true;
|
||||
|
@ -15,6 +15,7 @@ public class TransactionExecutor {
|
||||
static {
|
||||
instance = new TransactionExecutor();
|
||||
}
|
||||
|
||||
public static TransactionExecutor instance;
|
||||
private ExecutorService executor = Executors.newFixedThreadPool(1);
|
||||
|
||||
|
@ -65,7 +65,7 @@ public class MessageDecoder extends ByteToMessageDecoder {
|
||||
if (!((syncToken >> 24 & 0xFF) == 0x22 &&
|
||||
(syncToken >> 16 & 0xFF) == 0x40 &&
|
||||
(syncToken >> 8 & 0xFF) == 0x08 &&
|
||||
(syncToken & 0xFF) == 0x91 )) {
|
||||
(syncToken & 0xFF) == 0x91)) {
|
||||
|
||||
// TODO: Drop frame and continue.
|
||||
// A collision can happen (although rare)
|
||||
|
@ -6,6 +6,7 @@ import org.apache.maven.plugin.MojoFailureException;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
*
|
||||
* @author: Roman Mandeleil
|
||||
* Created on: 25/04/14 17:06
|
||||
*/
|
||||
|
@ -5,7 +5,8 @@ import org.antlr.v4.runtime.atn.PredictionMode;
|
||||
import org.antlr.v4.runtime.misc.Nullable;
|
||||
|
||||
public class ParserUtils {
|
||||
private ParserUtils() {}
|
||||
private ParserUtils() {
|
||||
}
|
||||
|
||||
public static <L extends Lexer> L getLexer(Class<L> lexerClass, String source) {
|
||||
CharStream input = new ANTLRInputStream(source);
|
||||
@ -19,7 +20,8 @@ public class ParserUtils {
|
||||
return lexer;
|
||||
}
|
||||
|
||||
public static <P extends Parser> P getParser(Class<? extends Lexer> lexerClass, Class<P> parserClass, String source) {
|
||||
public static <P extends Parser> P getParser(Class<? extends Lexer> lexerClass, Class<P> parserClass, String
|
||||
source) {
|
||||
Lexer lexer = getLexer(lexerClass, source);
|
||||
TokenStream tokens = new CommonTokenStream(lexer);
|
||||
|
||||
@ -49,7 +51,7 @@ public class ParserUtils {
|
||||
public AntlrParseException(int line, int posInLine, String msg, Throwable cause) {
|
||||
// posInLine comes in 0-indexed, but we want to 1-index it so it lines up with what editors say (they
|
||||
// tend to 1-index)
|
||||
super(String.format("at line %d column %d: %s", line, posInLine+1, msg), cause);
|
||||
super(String.format("at line %d column %d: %s", line, posInLine + 1, msg), cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
*
|
||||
* @author Roman Mandeleil
|
||||
* Created on: 13/05/14 19:37
|
||||
*/
|
||||
@ -169,7 +170,7 @@ public class SerpentCompiler {
|
||||
|
||||
lexaList.add(i, pos.toString());
|
||||
|
||||
for (int j = 0; j < (4 - bytesNum) ; ++j)
|
||||
for (int j = 0; j < (4 - bytesNum); ++j)
|
||||
lexaList.add(i, "0");
|
||||
|
||||
lexaList.add(i, "PUSH4");
|
||||
@ -194,7 +195,6 @@ public class SerpentCompiler {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param code
|
||||
* @param init
|
||||
* @return encoded bytes
|
||||
@ -213,11 +213,11 @@ public class SerpentCompiler {
|
||||
|
||||
// calc real code start position (after the init header)
|
||||
int pos = 10 + numBytes * 2;
|
||||
if (init != null) pos+=init.length;
|
||||
if (init != null) pos += init.length;
|
||||
|
||||
// @push_len @len PUSH1 @src_start PUSH1 0 CODECOPY @push_len @len 0 PUSH1 0 RETURN
|
||||
String header = String.format("[asm %s %s PUSH1 %d PUSH1 0 CODECOPY %s %s PUSH1 0 RETURN asm]",
|
||||
"PUSH" + numBytes, sb.toString(), pos , "PUSH" + numBytes, sb.toString());
|
||||
"PUSH" + numBytes, sb.toString(), pos, "PUSH" + numBytes, sb.toString());
|
||||
|
||||
byte[] headerMachine = compileAssemblyToMachine(header);
|
||||
|
||||
|
@ -14,6 +14,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
*
|
||||
* @author: Roman Mandeleil
|
||||
* Created on: 05/05/14 13:41
|
||||
*/
|
||||
@ -29,16 +30,16 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
public String visitParse(@NotNull SerpentParser.ParseContext ctx) {
|
||||
|
||||
String codeBlock = visit(ctx.block());
|
||||
int memSize = vars.size() * 32 - ( vars.size() > 0 ? 1 : 0);
|
||||
int memSize = vars.size() * 32 - (vars.size() > 0 ? 1 : 0);
|
||||
|
||||
String initMemCodeBlock = "";
|
||||
if ( ! arraysSize.isEmpty() && vars.size() > 0)
|
||||
if (!arraysSize.isEmpty() && vars.size() > 0)
|
||||
initMemCodeBlock = String.format(" 0 %d MSTORE8 ", memSize);
|
||||
|
||||
if (memSize == 0)
|
||||
codeBlock= codeBlock.replace("@vars_table@", "0");
|
||||
codeBlock = codeBlock.replace("@vars_table@", "0");
|
||||
else
|
||||
codeBlock= codeBlock.replace("@vars_table@", memSize + 1 + "");
|
||||
codeBlock = codeBlock.replace("@vars_table@", memSize + 1 + "");
|
||||
|
||||
return initMemCodeBlock + codeBlock;
|
||||
}
|
||||
@ -47,29 +48,29 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
public String visitParse_init_code_block(@NotNull SerpentParser.Parse_init_code_blockContext ctx) {
|
||||
|
||||
String initBlock = visit(ctx.block(0));
|
||||
int memSize = vars.size() * 32 - ( vars.size() > 0 ? 1 : 0);
|
||||
int memSize = vars.size() * 32 - (vars.size() > 0 ? 1 : 0);
|
||||
|
||||
String initMemInitBlock = "";
|
||||
if ( ! arraysSize.isEmpty() && vars.size() > 0)
|
||||
if (!arraysSize.isEmpty() && vars.size() > 0)
|
||||
initMemInitBlock = String.format(" 0 %d MSTORE8 ", memSize);
|
||||
|
||||
if (memSize == 0)
|
||||
initBlock= initBlock.replace("@vars_table@", "0");
|
||||
initBlock = initBlock.replace("@vars_table@", "0");
|
||||
else
|
||||
initBlock= initBlock.replace("@vars_table@", memSize + 1 + "");
|
||||
initBlock = initBlock.replace("@vars_table@", memSize + 1 + "");
|
||||
|
||||
vars.clear();
|
||||
String codeBlock = visit(ctx.block(1));
|
||||
memSize = vars.size() * 32 - ( vars.size() > 0 ? 1 : 0);
|
||||
memSize = vars.size() * 32 - (vars.size() > 0 ? 1 : 0);
|
||||
|
||||
if (memSize == 0)
|
||||
codeBlock= codeBlock.replace("@vars_table@", "0");
|
||||
codeBlock = codeBlock.replace("@vars_table@", "0");
|
||||
else
|
||||
codeBlock= codeBlock.replace("@vars_table@", memSize + 1 + "");
|
||||
codeBlock = codeBlock.replace("@vars_table@", memSize + 1 + "");
|
||||
|
||||
|
||||
String initMemCodeBlock = "";
|
||||
if ( ! arraysSize.isEmpty() && vars.size() > 0)
|
||||
if (!arraysSize.isEmpty() && vars.size() > 0)
|
||||
initMemCodeBlock = String.format(" 0 %d MSTORE8 ", memSize);
|
||||
|
||||
return String.format(" [init %s %s init] [code %s %s code] ", initMemInitBlock, initBlock,
|
||||
@ -81,7 +82,7 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
|
||||
StringBuffer retCode = new StringBuffer();
|
||||
|
||||
int endOfStmtLabel = labelIndex++ ;
|
||||
int endOfStmtLabel = labelIndex++;
|
||||
|
||||
// if body
|
||||
SerpentParser.BlockContext ifBlock = (SerpentParser.BlockContext) ctx.getChild(4);
|
||||
@ -155,7 +156,8 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
|
||||
String retCode =
|
||||
String.format(" LABEL_%d %s NOT REF_%d JUMPI %s REF_%d JUMP LABEL_%d ",
|
||||
whileStartRef, visitCondition(whileCondition), whileEndRef, visitBlock(whileBlock), whileStartRef, whileEndRef);
|
||||
whileStartRef, visitCondition(whileCondition), whileEndRef, visitBlock(whileBlock),
|
||||
whileStartRef, whileEndRef);
|
||||
return retCode;
|
||||
}
|
||||
|
||||
@ -287,14 +289,14 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
@Override
|
||||
public String visitArray_assign(@NotNull SerpentParser.Array_assignContext ctx) {
|
||||
|
||||
int order = this.arraysIndex.indexOf( ctx.VAR().toString());
|
||||
int order = this.arraysIndex.indexOf(ctx.VAR().toString());
|
||||
if (order == -1) {
|
||||
throw new Error("array with that name was not defined");
|
||||
}
|
||||
|
||||
//calcAllocatedBefore();
|
||||
int allocSize = 0;
|
||||
for (int i = 0; i < order; ++i ) {
|
||||
for (int i = 0; i < order; ++i) {
|
||||
String var = arraysIndex.get(i);
|
||||
allocSize += arraysSize.get(var);
|
||||
}
|
||||
@ -308,20 +310,20 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
@Override
|
||||
public String visitArray_retreive(@NotNull SerpentParser.Array_retreiveContext ctx) {
|
||||
|
||||
int order = this.arraysIndex.indexOf( ctx.VAR().toString());
|
||||
int order = this.arraysIndex.indexOf(ctx.VAR().toString());
|
||||
if (order == -1) {
|
||||
throw new Error("array with that name was not defined");
|
||||
}
|
||||
|
||||
int allocSize = 32;
|
||||
for (int i = 0; i < order; ++i ) {
|
||||
for (int i = 0; i < order; ++i) {
|
||||
String var = arraysIndex.get(i);
|
||||
allocSize += arraysSize.get(var);
|
||||
}
|
||||
|
||||
String index = visit(ctx.int_val());
|
||||
|
||||
return String.format(" 32 %s MUL %d ADD @vars_table@ ADD MLOAD ", index, allocSize );
|
||||
return String.format(" 32 %s MUL %d ADD @vars_table@ ADD MLOAD ", index, allocSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -332,13 +334,20 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
String operand1 = visit(ctx.mul_expr());
|
||||
|
||||
switch (ctx.OP_MUL().getText().toLowerCase()) {
|
||||
case "*": return operand0 + " " + operand1 + " MUL";
|
||||
case "/": return operand0 + " " + operand1 + " DIV";
|
||||
case "^": return operand0 + " " + operand1 + " EXP";
|
||||
case "%": return operand0 + " " + operand1 + " MOD";
|
||||
case "#/": return operand0 + " " + operand1 + " SDIV";
|
||||
case "#%": return operand0 + " " + operand1 + " SMOD";
|
||||
default: throw new UnknownOperandException(ctx.OP_MUL().getText());
|
||||
case "*":
|
||||
return operand0 + " " + operand1 + " MUL";
|
||||
case "/":
|
||||
return operand0 + " " + operand1 + " DIV";
|
||||
case "^":
|
||||
return operand0 + " " + operand1 + " EXP";
|
||||
case "%":
|
||||
return operand0 + " " + operand1 + " MOD";
|
||||
case "#/":
|
||||
return operand0 + " " + operand1 + " SDIV";
|
||||
case "#%":
|
||||
return operand0 + " " + operand1 + " SMOD";
|
||||
default:
|
||||
throw new UnknownOperandException(ctx.OP_MUL().getText());
|
||||
}
|
||||
}
|
||||
|
||||
@ -351,9 +360,12 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
String operand1 = visit(ctx.add_expr());
|
||||
|
||||
switch (ctx.OP_ADD().getText().toLowerCase()) {
|
||||
case "+": return operand0 + " " + operand1 + " ADD";
|
||||
case "-": return operand0 + " " + operand1 + " SUB";
|
||||
default: throw new UnknownOperandException(ctx.OP_ADD().getText());
|
||||
case "+":
|
||||
return operand0 + " " + operand1 + " ADD";
|
||||
case "-":
|
||||
return operand0 + " " + operand1 + " SUB";
|
||||
default:
|
||||
throw new UnknownOperandException(ctx.OP_ADD().getText());
|
||||
}
|
||||
}
|
||||
|
||||
@ -366,11 +378,16 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
String operand1 = visit(ctx.add_expr());
|
||||
|
||||
switch (ctx.OP_REL().getText().toLowerCase()) {
|
||||
case "<": return operand1 + " " + operand0 + " LT";
|
||||
case ">": return operand1 + " " + operand0 + " GT";
|
||||
case ">=": return operand1 + " " + operand0 + " LT NOT";
|
||||
case "<=": return operand1 + " " + operand0 + " GT NOT";
|
||||
default: throw new UnknownOperandException(ctx.OP_REL().getText());
|
||||
case "<":
|
||||
return operand1 + " " + operand0 + " LT";
|
||||
case ">":
|
||||
return operand1 + " " + operand0 + " GT";
|
||||
case ">=":
|
||||
return operand1 + " " + operand0 + " LT NOT";
|
||||
case "<=":
|
||||
return operand1 + " " + operand0 + " GT NOT";
|
||||
default:
|
||||
throw new UnknownOperandException(ctx.OP_REL().getText());
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,9 +400,12 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
String operand1 = visit(ctx.eq_exp());
|
||||
|
||||
switch (ctx.OP_EQ().getText().toLowerCase()) {
|
||||
case "==": return operand0 + " " + operand1 + " EQ";
|
||||
case "!=": return operand0 + " " + operand1 + " EQ NOT";
|
||||
default: throw new UnknownOperandException(ctx.OP_EQ().getText());
|
||||
case "==":
|
||||
return operand0 + " " + operand1 + " EQ";
|
||||
case "!=":
|
||||
return operand0 + " " + operand1 + " EQ NOT";
|
||||
default:
|
||||
throw new UnknownOperandException(ctx.OP_EQ().getText());
|
||||
}
|
||||
}
|
||||
|
||||
@ -398,8 +418,10 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
String operand1 = visit(ctx.and_exp());
|
||||
|
||||
switch (ctx.OP_AND().getText().toLowerCase()) {
|
||||
case "&": return operand0 + " " + operand1 + " AND";
|
||||
default: throw new UnknownOperandException(ctx.OP_AND().getText());
|
||||
case "&":
|
||||
return operand0 + " " + operand1 + " AND";
|
||||
default:
|
||||
throw new UnknownOperandException(ctx.OP_AND().getText());
|
||||
}
|
||||
}
|
||||
|
||||
@ -412,8 +434,10 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
String operand1 = visit(ctx.ex_or_exp());
|
||||
|
||||
switch (ctx.OP_EX_OR().getText().toLowerCase()) {
|
||||
case "xor": return operand0 + " " + operand1 + " XOR";
|
||||
default: throw new UnknownOperandException(ctx.OP_EX_OR().getText());
|
||||
case "xor":
|
||||
return operand0 + " " + operand1 + " XOR";
|
||||
default:
|
||||
throw new UnknownOperandException(ctx.OP_EX_OR().getText());
|
||||
}
|
||||
}
|
||||
|
||||
@ -426,8 +450,10 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
String operand1 = visit(ctx.in_or_exp());
|
||||
|
||||
switch (ctx.OP_IN_OR().getText().toLowerCase()) {
|
||||
case "|": return operand0 + " " + operand1 + " OR";
|
||||
default: throw new UnknownOperandException(ctx.OP_IN_OR().getText());
|
||||
case "|":
|
||||
return operand0 + " " + operand1 + " OR";
|
||||
default:
|
||||
throw new UnknownOperandException(ctx.OP_IN_OR().getText());
|
||||
}
|
||||
}
|
||||
|
||||
@ -440,9 +466,12 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
String operand1 = visit(ctx.log_and_exp());
|
||||
|
||||
switch (ctx.OP_LOG_AND().getText().toLowerCase()) {
|
||||
case "and": return operand0 + " " + operand1 + " NOT NOT MUL";
|
||||
case "&&": return operand0 + " " + operand1 + " NOT NOT MUL";
|
||||
default: throw new UnknownOperandException(ctx.OP_LOG_AND().getText());
|
||||
case "and":
|
||||
return operand0 + " " + operand1 + " NOT NOT MUL";
|
||||
case "&&":
|
||||
return operand0 + " " + operand1 + " NOT NOT MUL";
|
||||
default:
|
||||
throw new UnknownOperandException(ctx.OP_LOG_AND().getText());
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,9 +484,12 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
String operand1 = visit(ctx.log_or_exp());
|
||||
|
||||
switch (ctx.OP_LOG_OR().getText().toLowerCase()) {
|
||||
case "||": return operand0 + " " + operand1 + " DUP 4 PC ADD JUMPI POP SWAP POP";
|
||||
case "or": return operand0 + " " + operand1 + " DUP 4 PC ADD JUMPI POP SWAP POP";
|
||||
default: throw new UnknownOperandException(ctx.OP_LOG_OR().getText());
|
||||
case "||":
|
||||
return operand0 + " " + operand1 + " DUP 4 PC ADD JUMPI POP SWAP POP";
|
||||
case "or":
|
||||
return operand0 + " " + operand1 + " DUP 4 PC ADD JUMPI POP SWAP POP";
|
||||
default:
|
||||
throw new UnknownOperandException(ctx.OP_LOG_OR().getText());
|
||||
}
|
||||
}
|
||||
|
||||
@ -588,8 +620,8 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
|
||||
String randomArrayName = new String(HashUtil.randomPeerId());
|
||||
|
||||
int inSize = Integer.parseInt( inSizeCallParam );
|
||||
int outSize = Integer.parseInt( outSizeCallParam );
|
||||
int inSize = Integer.parseInt(inSizeCallParam);
|
||||
int outSize = Integer.parseInt(outSizeCallParam);
|
||||
|
||||
arraysSize.put(randomArrayName, inSize * 32 + 32);
|
||||
arraysIndex.add(randomArrayName);
|
||||
@ -604,10 +636,10 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
|
||||
// this code allocates the memory block for the out data,
|
||||
// and saves the size in typical array format [size, element_1, element_2, ...]
|
||||
String outArrSet = String.format( " %d MSIZE MSTORE 0 %d MSIZE ADD MSTORE8 ", outSizeVal, outSizeVal - 32 );
|
||||
String outArrSet = String.format(" %d MSIZE MSTORE 0 %d MSIZE ADD MSTORE8 ", outSizeVal, outSizeVal - 32);
|
||||
|
||||
return String.format("%d MSIZE %s %d %s %s %s %s CALL ",
|
||||
outSizeVal, outArrSet ,inSize * 32, loadInData, operand2, operand1, operand0);
|
||||
outSizeVal, outArrSet, inSize * 32, loadInData, operand2, operand1, operand0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -637,7 +669,7 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
int size = ctx.asm_symbol().getChildCount();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < size ; ++i) {
|
||||
for (int i = 0; i < size; ++i) {
|
||||
|
||||
String symbol = ctx.asm_symbol().children.get(i).toString();
|
||||
symbol = symbol.trim();
|
||||
@ -649,14 +681,16 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
if (match) {
|
||||
|
||||
int byteVal = Integer.parseInt(symbol);
|
||||
if (byteVal > 255 || byteVal < 0) throw new Error("In the [asm asm] block should be placed only byte range numbers");
|
||||
if (byteVal > 255 || byteVal < 0)
|
||||
throw new Error("In the [asm asm] block should be placed only byte range numbers");
|
||||
}
|
||||
|
||||
match = Pattern.matches("0[xX][0-9a-fA-F]+", symbol);
|
||||
if (match) {
|
||||
|
||||
int byteVal = Integer.parseInt(symbol.substring(2), 16);
|
||||
if (byteVal > 255 || byteVal < 0) throw new Error("In the [asm asm] block should be placed only byte range numbers");
|
||||
if (byteVal > 255 || byteVal < 0)
|
||||
throw new Error("In the [asm asm] block should be placed only byte range numbers");
|
||||
symbol = byteVal + "";
|
||||
}
|
||||
|
||||
@ -725,12 +759,12 @@ public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
|
||||
return Integer.parseInt(result);
|
||||
}
|
||||
|
||||
private String cleanMsgString (String code) {
|
||||
private String cleanMsgString(String code) {
|
||||
|
||||
String result = "";
|
||||
|
||||
Pattern pattern = Pattern.compile("<(.*?)>");
|
||||
result= code.replaceAll("<(.*?)>", "");
|
||||
result = code.replaceAll("<(.*?)>", "");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import org.iq80.leveldb.WriteBatch;
|
||||
|
||||
/**
|
||||
* www.ethereumJ.com
|
||||
*
|
||||
* @author: Nick Savers
|
||||
* Created on: 20/05/2014 10:44
|
||||
*/
|
||||
@ -92,7 +93,7 @@ public class Cache {
|
||||
public void undo() {
|
||||
Iterator<Map.Entry<ByteArrayWrapper, Node>> iter = this.nodes.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
if(iter.next().getValue().isDirty()) {
|
||||
if (iter.next().getValue().isDirty()) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
@ -115,11 +116,11 @@ public class Cache {
|
||||
return db;
|
||||
}
|
||||
|
||||
public String cacheDump(){
|
||||
public String cacheDump() {
|
||||
|
||||
StringBuffer cacheDump = new StringBuffer();
|
||||
|
||||
for (ByteArrayWrapper key : nodes.keySet()){
|
||||
for (ByteArrayWrapper key : nodes.keySet()) {
|
||||
|
||||
Node node = nodes.get(key);
|
||||
|
||||
|
@ -20,7 +20,7 @@ public class CollectFullSetOfNodes implements TrieImpl.ScanAction {
|
||||
nodes.add(hash);
|
||||
}
|
||||
|
||||
public Set<byte[]> getCollectedHashes(){
|
||||
public Set<byte[]> getCollectedHashes() {
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
|
@ -18,5 +18,7 @@ public class CountAllNodes implements TrieImpl.ScanAction {
|
||||
++counted;
|
||||
}
|
||||
|
||||
public int getCounted(){return counted;}
|
||||
public int getCounted() {
|
||||
return counted;
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ import org.ethereum.util.Value;
|
||||
* when length < 32 for the obvious reason that the function f(x) = x is reversible.
|
||||
*
|
||||
* www.ethereumJ.com
|
||||
*
|
||||
* @author Nick Savers
|
||||
* Created on: 20/05/2014 10:44
|
||||
*/
|
||||
|
@ -36,6 +36,7 @@ import org.spongycastle.util.encoders.Hex;
|
||||
* <b>Note:</b> the data isn't persisted unless `sync` is explicitly called.
|
||||
*
|
||||
* www.ethereumJ.com
|
||||
*
|
||||
* @author: Nick Savers
|
||||
* Created on: 20/05/2014 10:44
|
||||
*/
|
||||
@ -106,7 +107,7 @@ public class TrieImpl implements Trie {
|
||||
byte[] k = binToNibbles(key);
|
||||
Value c = new Value(this.get(this.root, k));
|
||||
|
||||
return (c == null)? null : c.asBytes();
|
||||
return (c == null) ? null : c.asBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,7 +127,7 @@ public class TrieImpl implements Trie {
|
||||
byte[] k = binToNibbles(key);
|
||||
|
||||
this.root = this.insertOrDelete(this.root, k, value);
|
||||
if(logger.isDebugEnabled()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Added key {} and value {}", Hex.toHexString(key), Hex.toHexString(value));
|
||||
logger.debug("New root-hash: {}", Hex.toHexString(this.getRootHash()));
|
||||
}
|
||||
@ -144,7 +145,7 @@ public class TrieImpl implements Trie {
|
||||
@Override
|
||||
public void delete(byte[] key) {
|
||||
delete(new String(key));
|
||||
if(logger.isDebugEnabled()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Deleted value for key {}", Hex.toHexString(key));
|
||||
logger.debug("New root-hash: {}", Hex.toHexString(this.getRootHash()));
|
||||
}
|
||||
@ -213,7 +214,7 @@ public class TrieImpl implements Trie {
|
||||
}
|
||||
|
||||
if (isEmptyNode(node)) {
|
||||
Object[] newNode = new Object[] { packNibbles(key), value };
|
||||
Object[] newNode = new Object[]{packNibbles(key), value};
|
||||
return this.putToCache(newNode);
|
||||
}
|
||||
|
||||
@ -227,7 +228,7 @@ public class TrieImpl implements Trie {
|
||||
|
||||
// Matching key pair (ie. there's already an object with this key)
|
||||
if (Arrays.equals(k, key)) {
|
||||
Object[] newNode = new Object[] {packNibbles(key), value};
|
||||
Object[] newNode = new Object[]{packNibbles(key), value};
|
||||
return this.putToCache(newNode);
|
||||
}
|
||||
|
||||
@ -242,8 +243,8 @@ public class TrieImpl implements Trie {
|
||||
|
||||
// Expand the 2 length slice to a 17 length slice
|
||||
// Create two nodes to putToCache into the new 17 length node
|
||||
Object oldNode = this.insert("", copyOfRange(k, matchingLength+1, k.length), v);
|
||||
Object newNode = this.insert("", copyOfRange(key, matchingLength+1, key.length), value);
|
||||
Object oldNode = this.insert("", copyOfRange(k, matchingLength + 1, k.length), v);
|
||||
Object newNode = this.insert("", copyOfRange(key, matchingLength + 1, key.length), value);
|
||||
|
||||
// Create an expanded slice
|
||||
Object[] scaledSlice = emptyStringSlice(17);
|
||||
@ -258,7 +259,7 @@ public class TrieImpl implements Trie {
|
||||
// End of the chain, return
|
||||
return newHash;
|
||||
} else {
|
||||
Object[] newNode = new Object[] { packNibbles(copyOfRange(key, 0, matchingLength)), newHash};
|
||||
Object[] newNode = new Object[]{packNibbles(copyOfRange(key, 0, matchingLength)), newHash};
|
||||
return this.putToCache(newNode);
|
||||
}
|
||||
} else {
|
||||
@ -296,9 +297,9 @@ public class TrieImpl implements Trie {
|
||||
Object newNode;
|
||||
if (child.length() == PAIR_SIZE) {
|
||||
byte[] newKey = concatenate(k, unpackToNibbles(child.get(0).asBytes()));
|
||||
newNode = new Object[] {packNibbles(newKey), child.get(1).asObj()};
|
||||
newNode = new Object[]{packNibbles(newKey), child.get(1).asObj()};
|
||||
} else {
|
||||
newNode = new Object[] {currentNode.get(0).asString(), hash};
|
||||
newNode = new Object[]{currentNode.get(0).asString(), hash};
|
||||
}
|
||||
return this.putToCache(newNode);
|
||||
} else {
|
||||
@ -324,14 +325,14 @@ public class TrieImpl implements Trie {
|
||||
|
||||
Object[] newNode = null;
|
||||
if (amount == 16) {
|
||||
newNode = new Object[] { packNibbles(new byte[] {16} ), itemList[amount]};
|
||||
newNode = new Object[]{packNibbles(new byte[]{16}), itemList[amount]};
|
||||
} else if (amount >= 0) {
|
||||
Value child = this.getNode(itemList[amount]);
|
||||
if (child.length() == PAIR_SIZE) {
|
||||
key = concatenate(new byte[]{amount}, unpackToNibbles(child.get(0).asBytes()));
|
||||
newNode = new Object[] {packNibbles(key), child.get(1).asObj()};
|
||||
newNode = new Object[]{packNibbles(key), child.get(1).asObj()};
|
||||
} else if (child.length() == LIST_SIZE) {
|
||||
newNode = new Object[] { packNibbles(new byte[]{amount}), itemList[amount]};
|
||||
newNode = new Object[]{packNibbles(new byte[]{amount}), itemList[amount]};
|
||||
}
|
||||
} else {
|
||||
newNode = itemList;
|
||||
@ -466,7 +467,7 @@ public class TrieImpl implements Trie {
|
||||
logger.info("Garbage collection time: [{}ms]", System.currentTimeMillis() - startTime);
|
||||
}
|
||||
|
||||
public void printFootPrint(){
|
||||
public void printFootPrint() {
|
||||
|
||||
this.getCache().getNodes();
|
||||
}
|
||||
@ -511,7 +512,7 @@ public class TrieImpl implements Trie {
|
||||
public void doOnNode(byte[] hash, Value node);
|
||||
}
|
||||
|
||||
public boolean validate(){
|
||||
public boolean validate() {
|
||||
|
||||
if (cache.get(getRootHash()) != null)
|
||||
return true;
|
||||
|
@ -3,6 +3,7 @@ package org.ethereum.trie;
|
||||
import java.util.List;
|
||||
|
||||
import org.ethereum.util.Value;
|
||||
|
||||
import static org.ethereum.util.CompactEncoder.unpackToNibbles;
|
||||
|
||||
/*
|
||||
@ -32,7 +33,7 @@ public class TrieIterator {
|
||||
if (currentNode.get(1).asString() == "") {
|
||||
this.workNode(currentNode.get(1));
|
||||
} else {
|
||||
if (k[k.length-1] == 16) {
|
||||
if (k[k.length - 1] == 16) {
|
||||
this.values.add(currentNode.get(1).asString());
|
||||
} else {
|
||||
this.shas.add(currentNode.get(1).asBytes());
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user