diff --git a/ethereumj-core/src/main/java/org/ethereum/config/SystemProperties.java b/ethereumj-core/src/main/java/org/ethereum/config/SystemProperties.java index eb3f2683..de1835d5 100644 --- a/ethereumj-core/src/main/java/org/ethereum/config/SystemProperties.java +++ b/ethereumj-core/src/main/java/org/ethereum/config/SystemProperties.java @@ -215,6 +215,13 @@ public class SystemProperties { return prop.getProperty("hello.phrase"); } + public String rootHashStart() { + if(prop.isEmpty()) return null; + String hash = prop.getProperty("root.hash.start"); + if (hash == null || hash.equals("-1")) return null; + + return prop.getProperty("root.hash.start"); + } public static void main(String args[]) { SystemProperties systemProperties = new SystemProperties(); diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Account.java b/ethereumj-core/src/main/java/org/ethereum/core/Account.java index 13815b7a..b287c6dc 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Account.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Account.java @@ -3,29 +3,28 @@ package org.ethereum.core; import java.math.BigInteger; import org.ethereum.crypto.ECKey; +import org.ethereum.manager.WorldManager; import org.ethereum.util.Utils; /** * Representation of an actual account or contract */ -public class Account extends AccountState { +public class Account { private ECKey ecKey; private byte[] address; public Account() { this.ecKey = new ECKey(Utils.getRandom()); + address = this.ecKey.getAddress(); } public Account(ECKey ecKey) { this.ecKey = ecKey; + address = this.ecKey.getAddress(); } - public Account(ECKey ecKey, BigInteger nonce, BigInteger balance) { - super(nonce, balance); - this.ecKey = ecKey; - } - + public ECKey getEcKey() { return ecKey; } @@ -37,4 +36,34 @@ public class Account extends AccountState { public void setAddress(byte[] address) { this.address = address; } + + public AccountState getAccountState(){ + AccountState accountState = + WorldManager.getInstance().getRepository().getAccountState(this.address); + + return accountState; + } + + public BigInteger getBalance() { + + AccountState accountState = + WorldManager.getInstance().getRepository().getAccountState(this.address); + + if (accountState != null) + return accountState.getBalance(); + + return null; + } + + + public BigInteger getNonce() { + + AccountState accountState = + WorldManager.getInstance().getRepository().getAccountState(this.address); + + if (accountState != null) + return accountState.getNonce(); + + return null; + } } diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Wallet.java b/ethereumj-core/src/main/java/org/ethereum/core/Wallet.java index 8db40398..44e0842e 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Wallet.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Wallet.java @@ -76,7 +76,8 @@ public class Wallet { public AccountState getAccountState(byte[] addressBytes) { String address = Hex.toHexString(addressBytes); - return rows.get(address); + + return rows.get(address).getAccountState(); } public BigInteger getBalance(byte[] addressBytes) { @@ -142,14 +143,14 @@ public class Wallet { if (sender != null) { BigInteger value = new BigInteger(-1, transaction.getValue()); - sender.addToBalance(value); - sender.incrementNonce(); +// sender.addToBalance(value); +// sender.incrementNonce(); } byte[] receiveAddress = transaction.getReceiveAddress(); Account receiver = rows.get(Hex.toHexString(receiveAddress)); if (receiver != null) { - receiver.addToBalance(new BigInteger(1, transaction.getValue())); +// receiver.addToBalance(new BigInteger(1, transaction.getValue())); } this.notifyListeners(); } diff --git a/ethereumj-core/src/main/java/org/ethereum/db/Repository.java b/ethereumj-core/src/main/java/org/ethereum/db/Repository.java index 78f0d91d..7b147758 100644 --- a/ethereumj-core/src/main/java/org/ethereum/db/Repository.java +++ b/ethereumj-core/src/main/java/org/ethereum/db/Repository.java @@ -156,9 +156,8 @@ public class Repository { } logger.info( "*** Loaded up to block [ {} ] with stateRoot [ {} ]", - blockchain.getLastBlock().getNumber(), Hex - .toHexString(blockchain.getLastBlock() - .getStateRoot())); + blockchain.getLastBlock().getNumber(), + Hex.toHexString(blockchain.getLastBlock().getStateRoot())); } } finally { // Make sure you close the iterator to avoid resource leaks. @@ -168,9 +167,20 @@ public class Repository { logger.error(e.getMessage(), e); } } - // Update world state to latest loaded block from db - this.worldState.setRoot(blockchain.getLastBlock().getStateRoot()); - + + 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.worldState.setRoot(rootHash); + + } else{ + + // Update world state to latest loaded block from db + this.worldState.setRoot(blockchain.getLastBlock().getStateRoot()); + } + return blockchain; } diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java index 3487d751..9dd00be6 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/Ethereum.java @@ -71,9 +71,10 @@ public interface Ethereum { public void addListener(EthereumListener listener); - public ClientPeer getDefaultPeer(); + public boolean isConnected(); + public void close(); diff --git a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index f178b75c..6a0c0b30 100644 --- a/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/ethereumj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -155,4 +155,8 @@ public class EthereumImpl implements Ethereum { return peer; } + @Override + public boolean isConnected() { + return WorldManager.getInstance().getActivePeer() != null; + } } diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java index bb9fe6c7..7959653f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java @@ -42,6 +42,9 @@ public class WorldManager { private static final class WorldManagerHolder { private static final WorldManager instance = new WorldManager(); + static{ + instance.init(); + } } private WorldManager() { @@ -54,19 +57,23 @@ public class WorldManager { peerDiscovery = new PeerDiscovery(peers); - this.wallet = new Wallet(); - - byte[] cowAddr = HashUtil.sha3("cow".getBytes()); - ECKey key = ECKey.fromPrivate(cowAddr); - wallet.importKey(cowAddr); - - AccountState state = wallet.getAccountState(key.getAddress()); - state.addToBalance(BigInteger.valueOf(2).pow(200)); - - String secret = CONFIG.coinbaseSecret(); - byte[] cbAddr = HashUtil.sha3(secret.getBytes()); - wallet.importKey(cbAddr); } + + public void init(){ + this.wallet = new Wallet(); + + byte[] cowAddr = HashUtil.sha3("cow".getBytes()); + ECKey key = ECKey.fromPrivate(cowAddr); + wallet.importKey(cowAddr); + +// AccountState state = wallet.getAccountState(key.getAddress()); +// state.addToBalance(BigInteger.valueOf(2).pow(200)); + + String secret = CONFIG.coinbaseSecret(); + byte[] cbAddr = HashUtil.sha3(secret.getBytes()); + wallet.importKey(cbAddr); + + } public static WorldManager getInstance() { return WorldManagerHolder.instance; diff --git a/ethereumj-core/src/main/resources/system.properties b/ethereumj-core/src/main/resources/system.properties index 747d0db8..dfa4a759 100644 --- a/ethereumj-core/src/main/resources/system.properties +++ b/ethereumj-core/src/main/resources/system.properties @@ -146,4 +146,16 @@ project.version = PROJECT.VERSION # hello phrase will be included in # the hello message of the peer -hello.phrase = RJ \ No newline at end of file +hello.phrase = RJ + +# this property used +# mostly for a debug purpose +# so if you don't know exactly how +# to apply it leave to be [-1] +# +# ADVANCED: if we want to load a root hash +# for db not from the saved block chain (last block) +# but any manual hash this property will help. +# values [-1] - load from db +# [hex hash 32 bytes] root hash +root.hash.start = -1 diff --git a/ethereumj-studio/src/main/java/org/ethereum/gui/PayOutDialog.java b/ethereumj-studio/src/main/java/org/ethereum/gui/PayOutDialog.java index 3cfd378f..aad05778 100644 --- a/ethereumj-studio/src/main/java/org/ethereum/gui/PayOutDialog.java +++ b/ethereumj-studio/src/main/java/org/ethereum/gui/PayOutDialog.java @@ -1,10 +1,7 @@ package org.ethereum.gui; import org.ethereum.core.Account; -import org.ethereum.core.AccountState; import org.ethereum.core.Transaction; -import org.ethereum.manager.WorldManager; -import org.ethereum.net.client.ClientPeer; import org.spongycastle.util.BigIntegers; import org.spongycastle.util.encoders.Hex; @@ -29,7 +26,7 @@ class PayOutDialog extends JDialog implements MessageAwareDialog { private PayOutDialog dialog; - private AccountState accountState = null; + private Account account = null; private JLabel statusMsg = null; private final JTextField receiverInput; @@ -40,7 +37,7 @@ class PayOutDialog extends JDialog implements MessageAwareDialog { super(parent, "Payout details: ", false); dialog = this; - this.accountState = account; + this.account = account; receiverInput = new JTextField(18); GUIUtils.addStyle(receiverInput, "Pay to:"); @@ -107,18 +104,16 @@ class PayOutDialog extends JDialog implements MessageAwareDialog { BigInteger value = new BigInteger(amountInput.getText()); byte[] address = Hex.decode(receiverInput.getText()); - // Client - ClientPeer peer = WorldManager.getInstance().getActivePeer(); - if (peer == null) { + if (!UIEthereumManager.ethereum.isConnected()) { dialog.alertStatusMsg("Not connected to any peer"); return; } byte[] senderPrivKey = account.getEcKey().getPrivKeyBytes(); - byte[] nonce = accountState.getNonce() == BigInteger.ZERO ? null : accountState.getNonce().toByteArray(); + byte[] nonce = PayOutDialog.this.account.getNonce() == BigInteger.ZERO ? null : PayOutDialog.this.account.getNonce().toByteArray(); - byte[] gasPrice = BigInteger.valueOf( WorldManager.getInstance().getBlockchain().getGasPrice()).toByteArray(); + byte[] gasPrice = BigInteger.valueOf(UIEthereumManager.ethereum.getBlockChain().getGasPrice()).toByteArray(); Transaction tx = new Transaction(nonce, gasPrice, BigIntegers .asUnsignedByteArray(fee), address, BigIntegers @@ -199,8 +194,8 @@ class PayOutDialog extends JDialog implements MessageAwareDialog { // check if the tx is affordable BigInteger ammountValue = new BigInteger(amountText); BigInteger feeValue = new BigInteger(feeText); - BigInteger gasPrice = BigInteger.valueOf(WorldManager.getInstance().getBlockchain().getGasPrice()); - BigInteger currentBalance = accountState.getBalance(); + BigInteger gasPrice = BigInteger.valueOf(UIEthereumManager.ethereum.getBlockChain().getGasPrice()); + BigInteger currentBalance = account.getBalance(); boolean canAfford = gasPrice.multiply(feeValue).add(ammountValue).compareTo(currentBalance) != 1;