diff --git a/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java b/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java index 666cdd35..a004f87d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java +++ b/ethereumj-core/src/main/java/org/ethereum/core/Blockchain.java @@ -48,7 +48,6 @@ public class Blockchain { public Blockchain(Wallet wallet) { this.db = WorldManager.instance.chainDB; this.wallet = wallet; - this.loadChain(); } public Block getLastBlock() { @@ -162,24 +161,31 @@ public class Blockchain { public void loadChain() { DBIterator iterator = db.iterator(); try { - if (!iterator.hasNext()) { - logger.info("DB is empty - adding Genesis"); - Block genesis = Genesis.getInstance(); + if (index.size() == 0) { + logger.info("DB is empty - adding Genesis"); + Block genesis = Genesis.getInstance(); this.addBlock(genesis); - logger.debug("Block: " + genesis.getNumber() + " ---> " + genesis.toFlatString()); - db.put(genesis.getParentHash(), genesis.getEncoded()); - } else { - logger.debug("Displaying blocks stored in DB sorted on blocknumber"); - byte[] parentHash = Genesis.PARENT_HASH; // get Genesis block by parentHash - for (iterator.seekToFirst(); iterator.hasNext(); iterator.next()) { - byte[] parentRLP = db.get(parentHash); - if (parentRLP == null) return; + logger.debug("Block: " + genesis.getNumber() + " ---> " + genesis.toFlatString()); + db.put(genesis.getParentHash(), genesis.getEncoded()); + } + + logger.debug("Displaying blocks stored in DB sorted on blocknumber"); + byte[] parentHash = Genesis.PARENT_HASH; // get Genesis block by parentHash + for (iterator.seekToFirst(); iterator.hasNext(); iterator.next()) { + + byte[] parentRLP = db.get(parentHash); + if (parentRLP == null) return; + + Block block = new Block(parentRLP); + this.addBlock(block); + + // in case of cold load play the contracts + WorldManager.instance.applyBlock(block); + + if (logger.isDebugEnabled()) + logger.debug("Block: " + getLastBlock().getNumber() + " ---> " + getLastBlock().toFlatString()); + parentHash = getLastBlock().getHash(); - this.addBlock(new Block(parentRLP)); - if (logger.isDebugEnabled()) - logger.debug("Block: " + getLastBlock().getNumber() + " ---> " + getLastBlock().toFlatString()); - parentHash = getLastBlock().getHash(); - } } } finally { // Make sure you close the iterator to avoid resource leaks. diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/BlockChainTable.java b/ethereumj-core/src/main/java/org/ethereum/gui/BlockChainTable.java index 9cea4ae3..e5996139 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/BlockChainTable.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/BlockChainTable.java @@ -2,6 +2,7 @@ package org.ethereum.gui; import org.ethereum.core.Block; import org.ethereum.manager.MainData; +import org.ethereum.manager.WorldManager; import javax.swing.*; import javax.swing.table.DefaultTableCellRenderer; @@ -74,9 +75,9 @@ public class BlockChainTable extends JFrame { @Override public void actionPerformed(ActionEvent e) { - if (MainData.instance.getBlockchain().getSize() - 1 < lastFindIndex) return; + if (WorldManager.instance.getBlockChain().getSize() - 1 < lastFindIndex) return; - Block block = MainData.instance.getBlockchain().getByNumber(lastFindIndex); + Block block = WorldManager.instance.getBlockChain().getByNumber(lastFindIndex); StringSelection stsel = new StringSelection(block.toString()); Clipboard system = Toolkit.getDefaultToolkit().getSystemClipboard(); system.setContents(stsel,stsel); @@ -96,10 +97,10 @@ public class BlockChainTable extends JFrame { return; } - for (int i = lastFindIndex + 1; i < MainData.instance.getBlockchain().getSize(); ++i) { + for (int i = lastFindIndex + 1; i < WorldManager.instance.getBlockChain().getSize(); ++i) { - if (MainData.instance.getBlockchain().getSize() - 1 < i) return; - Block block = MainData.instance.getBlockchain().getByNumber(i); + if (WorldManager.instance.getBlockChain().getSize() - 1 < i) return; + Block block = WorldManager.instance.getBlockChain().getByNumber(i); boolean found = block.toString().toLowerCase().contains(toFind.toLowerCase()); if (found) { // todo: now we find the first occur diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/BlockTableModel.java b/ethereumj-core/src/main/java/org/ethereum/gui/BlockTableModel.java index 733404cf..49752b0f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/BlockTableModel.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/BlockTableModel.java @@ -2,6 +2,7 @@ package org.ethereum.gui; import org.ethereum.core.Block; import org.ethereum.manager.MainData; +import org.ethereum.manager.WorldManager; import javax.swing.table.AbstractTableModel; @@ -16,7 +17,7 @@ public class BlockTableModel extends AbstractTableModel { public int getRowCount() { fireTableDataChanged(); - int rowCount = MainData.instance.getBlockchain().getSize(); + int rowCount = WorldManager.instance.getBlockChain().getSize(); return rowCount; } @@ -31,7 +32,7 @@ public class BlockTableModel extends AbstractTableModel { // byte[] hash = MainData.instance.getAllBlocks().get(rowIndex).getHash(); // return Hex.toHexString(hash); - Block block = MainData.instance.getBlockchain().getByNumber(rowIndex); + Block block = WorldManager.instance.getBlockChain().getByNumber(rowIndex); if (block == null) return ""; return block.toString(); diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/ContractCallDialog.java b/ethereumj-core/src/main/java/org/ethereum/gui/ContractCallDialog.java index 795cac7e..e0930598 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/ContractCallDialog.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/ContractCallDialog.java @@ -1,5 +1,6 @@ package org.ethereum.gui; +import com.sun.javafx.binding.StringFormatter; import org.ethereum.core.Account; import org.ethereum.core.AccountState; import org.ethereum.core.ContractDetails; @@ -9,6 +10,7 @@ import org.ethereum.manager.WorldManager; import org.ethereum.net.client.ClientPeer; import org.ethereum.util.ByteUtil; import org.ethereum.util.Utils; +import org.ethereum.vm.DataWord; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.util.BigIntegers; @@ -16,17 +18,22 @@ import org.spongycastle.util.encoders.Hex; import javax.swing.*; import javax.swing.border.Border; +import javax.swing.border.EtchedBorder; +import javax.swing.border.TitledBorder; import javax.swing.plaf.ComboBoxUI; import javax.swing.plaf.basic.BasicComboBoxUI; import javax.swing.plaf.basic.BasicComboPopup; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableModel; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; +import java.awt.event.*; import java.math.BigInteger; import java.net.URL; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; /** * www.ethereumJ.com @@ -42,8 +49,14 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{ JComboBox creatorAddressCombo; final JTextField gasInput; final JTextField contractAddrInput; + + JScrollPane contractDataInput; JTextArea msgDataTA; + JLabel statusMsg = null; + JLabel playLabel = null; + JLabel rejectLabel = null; + JLabel approveLabel = null; public ContractCallDialog(Frame parent) { super(parent, "Call Contract: ", false); @@ -51,6 +64,20 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{ contractAddrInput = new JTextField(5); GUIUtils.addStyle(contractAddrInput, "Contract Address: "); + contractAddrInput.addFocusListener(new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + populateContractDetails(); + } + }); + + } + }); + + contractAddrInput.setBounds(70, 30, 350, 45); this.getContentPane().add(contractAddrInput); @@ -60,9 +87,9 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{ msgDataTA = new JTextArea(); msgDataTA.setLineWrap(true); - JScrollPane contractDataInput = new JScrollPane(msgDataTA); + contractDataInput = new JScrollPane(msgDataTA); GUIUtils.addStyle(msgDataTA, null, false); - GUIUtils.addStyle(contractDataInput, "Data:"); + GUIUtils.addStyle(contractDataInput, "Input:"); msgDataTA.setText(""); msgDataTA.setCaretPosition(0); @@ -78,20 +105,19 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{ URL rejectIconURL = ClassLoader.getSystemResource("buttons/reject.png"); ImageIcon rejectIcon = new ImageIcon(rejectIconURL); - JLabel rejectLabel = new JLabel(rejectIcon); + rejectLabel = new JLabel(rejectIcon); rejectLabel.setToolTipText("Cancel"); rejectLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); URL playIconURL = ClassLoader.getSystemResource("buttons/play.png"); ImageIcon playIcon = new ImageIcon(playIconURL); - JLabel playLabel = new JLabel(playIcon); + playLabel = new JLabel(playIcon); playLabel.setToolTipText("Play Drafted"); playLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); playLabel.addMouseListener( new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - ContractCallDialog.this.playContractCall(); }} ); @@ -118,7 +144,7 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{ URL approveIconURL = ClassLoader.getSystemResource("buttons/approve.png"); ImageIcon approveIcon = new ImageIcon(approveIconURL); - JLabel approveLabel = new JLabel(approveIcon); + approveLabel = new JLabel(approveIcon); approveLabel.setToolTipText("Submit the transaction"); approveLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); @@ -157,7 +183,7 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{ editor.setForeground(Color.RED); Collection accounts = - MainData.instance.getWallet().getAccountCollection(); + WorldManager.instance.getWallet().getAccountCollection(); for (Account account : accounts){ creatorAddressCombo.addItem(new AccountWrapper(account)); @@ -191,7 +217,7 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{ ((AbstractButton) creatorAddressCombo.getComponent(i)).setBorder(line); } } - creatorAddressCombo.setBounds(73, 267, 230, 36); + creatorAddressCombo.setBounds(70, 267, 230, 36); this.getContentPane().add(creatorAddressCombo); this.getContentPane().revalidate(); @@ -199,6 +225,117 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{ this.setResizable(false); } + private void populateContractDetails() { + + String contractAddr = contractAddrInput.getText(); + if (!Pattern.matches("[0-9a-fA-F]+", contractAddr) || (contractAddr.length() != 40)){ + return; + } + + byte[] contractAddress = Hex.decode( contractAddr ); + byte[] contractStateB = WorldManager.instance.worldState.get(contractAddress); + if (contractStateB == null || contractStateB.length == 0){ + return; + } + + AccountState contractState = new AccountState(contractStateB); + final byte[] programCode = WorldManager.instance.chainDB.get(contractState.getCodeHash()); + if (programCode == null || programCode.length == 0){ + return; + } + + byte[] contractDetailsB = + WorldManager.instance.detaildDB.get(contractAddress); + + ContractDetails contractDetails = null; + final Map storageMap = new HashMap(); + + if (contractDetailsB != null){ + + contractDetails = new ContractDetails(contractDetailsB); + Map tmpStorage = contractDetails.getStorage(); + if (tmpStorage != null){ + for (DataWord key : tmpStorage.keySet()){ + String keyToSave = Hex.toHexString (key.getNoLeadZeroesData()); + String valueToSave = Hex.toHexString (tmpStorage.get(key).getNoLeadZeroesData()); + storageMap.put(keyToSave, valueToSave); + } + } + } + + contractDataInput.setBounds(70, 80, 350, 145); + contractDataInput.setViewportView(msgDataTA); + + URL expandIconURL = ClassLoader.getSystemResource("buttons/add-23x23.png"); + ImageIcon expandIcon = new ImageIcon(expandIconURL); + final JLabel expandLabel = new JLabel(expandIcon); + expandLabel.setToolTipText("Cancel"); + expandLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); + expandLabel.setBounds(235, 232, 23, 23); + this.getContentPane().add(expandLabel); + expandLabel.setVisible(true); + + final Border border = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED); + final JPanel detailPanel = new JPanel(); + detailPanel.setBorder(border); + detailPanel.setBounds(135, 242, 230, 2); + + final JPanel spacer = new JPanel(); + spacer.setForeground(Color.white); + spacer.setBackground(Color.white); + spacer.setBorder(null); + spacer.setBounds(225, 232, 40, 20); + + this.getContentPane().add(spacer); + this.getContentPane().add(detailPanel); + + + expandLabel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + ContractCallDialog.this.setSize(500, 530); + + ContractCallDialog.this.creatorAddressCombo.setBounds(70, 367, 230, 36); + ContractCallDialog.this.gasInput.setBounds(330, 360, 90, 45); + ContractCallDialog.this.rejectLabel.setBounds(260, 425, 45, 45); + ContractCallDialog.this.approveLabel.setBounds(200, 425, 45, 45); + ContractCallDialog.this.statusMsg.setBounds(50, 460, 400, 50); + + spacer.setVisible(false); + expandLabel.setVisible(false); + detailPanel.setVisible(false); + + + JTextField contractCode = new JTextField(15); + contractCode.setText(Hex.toHexString( programCode )); + GUIUtils.addStyle(contractCode, "Code: "); + contractCode.setBounds(70, 230, 350, 45); + + JTable storage = new JTable(2, 2); + storage.setTableHeader(null); + storage.setShowGrid(false); + storage.setIntercellSpacing(new Dimension(15, 0)); + storage.setCellSelectionEnabled(false); + GUIUtils.addStyle(storage); + + JTableStorageModel tableModel = new JTableStorageModel(storageMap); + storage.setModel(tableModel); + + JScrollPane scrollPane = new JScrollPane(storage); + scrollPane.setBorder(null); + scrollPane.getViewport().setBackground(Color.WHITE); + scrollPane.setBounds(70, 290, 350, 50); + + + ContractCallDialog.this.getContentPane().add(contractCode); + ContractCallDialog.this.getContentPane().add(scrollPane); + } + }); + + + this.repaint(); + } + private void playContractCall() { @@ -226,7 +363,7 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{ Transaction tx = createTransaction(); if (tx == null) return; - ProgramPlayDialog.createAndShowGUI(programCode, tx, MainData.instance.getBlockchain().getLastBlock(), contractDetails); + ProgramPlayDialog.createAndShowGUI(programCode, tx, WorldManager.instance.getBlockChain().getLastBlock(), contractDetails); } protected JRootPane createRootPane() { @@ -355,5 +492,38 @@ class ContractCallDialog extends JDialog implements MessageAwareDialog{ return result; } } + + private class JTableStorageModel extends DefaultTableModel { + private JTableStorageModel(Map data) { + + if (data != null){ + + this.setColumnCount(2); + this.setRowCount(data.size()); + + int i = 0; + for (String key : data.keySet()){ + this.setValueAt(key, i, 0); + this.setValueAt(data.get(key), i, 1); + ++i; + } + } + } + } + + + public static void main(String args[]){ + WorldManager.instance.getWallet(); + WorldManager.instance.loadChain(); + ContractCallDialog ccd = new ContractCallDialog(null); + ccd.setVisible(true); + ccd.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + ccd.addWindowListener(new WindowAdapter() { + @Override + public void windowClosed(WindowEvent e) { + WorldManager.instance.close(); + } + }); + } } diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/ContractSubmitDialog.java b/ethereumj-core/src/main/java/org/ethereum/gui/ContractSubmitDialog.java index d7ca24f7..28f80f36 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/ContractSubmitDialog.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/ContractSubmitDialog.java @@ -109,7 +109,7 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog { contractAddrInput.setText(Hex.toHexString(tx.getContractAddress())); ProgramPlayDialog.createAndShowGUI(tx.getData(), tx, - MainData.instance.getBlockchain().getLastBlock(), null); + WorldManager.instance.getBlockChain().getLastBlock(), null); }} ); @@ -174,7 +174,7 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog { editor.setForeground(Color.RED); Collection accounts = - MainData.instance.getWallet().getAccountCollection(); + WorldManager.instance.getWallet().getAccountCollection(); for (Account account : accounts){ creatorAddressCombo.addItem(new AccountWrapper(account)); @@ -314,7 +314,7 @@ class ContractSubmitDialog extends JDialog implements MessageAwareDialog { Account account = ((AccountWrapper)creatorAddressCombo.getSelectedItem()).getAccount(); BigInteger currentBalance = account.getState().getBalance(); - BigInteger gasPrice = BigInteger.valueOf(MainData.instance.getBlockchain().getGasPrice()); + BigInteger gasPrice = BigInteger.valueOf(WorldManager.instance.getBlockChain().getGasPrice()); BigInteger gasInput = new BigInteger( this.gasInput.getText()); boolean canAfford = currentBalance.compareTo(gasPrice.multiply(gasInput)) >= 0; diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/DialogWorker.java b/ethereumj-core/src/main/java/org/ethereum/gui/DialogWorker.java index d5d010be..9a939927 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/DialogWorker.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/DialogWorker.java @@ -2,6 +2,7 @@ package org.ethereum.gui; import org.ethereum.core.Transaction; import org.ethereum.manager.MainData; +import org.ethereum.manager.WorldManager; import org.ethereum.net.submit.TransactionExecutor; import org.ethereum.net.submit.TransactionTask; import org.slf4j.Logger; @@ -58,7 +59,7 @@ public class DialogWorker extends SwingWorker { } dialog.infoStatusMsg("Transaction got approved"); - MainData.instance.getWallet().applyTransaction(tx); + WorldManager.instance.getWallet().applyTransaction(tx); return null; } } diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/GUIUtils.java b/ethereumj-core/src/main/java/org/ethereum/gui/GUIUtils.java index 5893aa36..7fd1f072 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/GUIUtils.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/GUIUtils.java @@ -64,6 +64,11 @@ public class GUIUtils { jScrollPane.setHorizontalScrollBar(null); } + public static void addStyle(JTable jTable){ + jTable.setForeground(new Color(143, 170, 220)); + jTable.setBackground(Color.WHITE); + jTable.setFont(new Font("Monospaced", 0, 13)); + } public static String getHexStyledText(byte[] data){ String[] dataHex = Hex.toHexString(data).split("(?<=\\G.{2})"); diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java b/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java index 2fe2a898..64086228 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java @@ -4,6 +4,7 @@ import org.ethereum.core.Account; import org.ethereum.core.AccountState; import org.ethereum.core.Transaction; import org.ethereum.manager.MainData; +import org.ethereum.manager.WorldManager; import org.ethereum.net.client.ClientPeer; import org.spongycastle.util.BigIntegers; import org.spongycastle.util.encoders.Hex; @@ -118,7 +119,7 @@ class PayOutDialog extends JDialog implements MessageAwareDialog { byte[] senderPrivKey = account.getEcKey().getPrivKeyBytes(); byte[] nonce = addressState.getNonce() == BigInteger.ZERO ? null : addressState.getNonce().toByteArray(); - byte[] gasPrice = BigInteger.valueOf( MainData.instance.getBlockchain().getGasPrice()).toByteArray(); + byte[] gasPrice = BigInteger.valueOf( WorldManager.instance.getBlockChain().getGasPrice()).toByteArray(); Transaction tx = new Transaction(nonce, gasPrice, BigIntegers .asUnsignedByteArray(fee), address, BigIntegers @@ -193,7 +194,7 @@ 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(MainData.instance.getBlockchain().getGasPrice()); + BigInteger gasPrice = BigInteger.valueOf(WorldManager.instance.getBlockChain().getGasPrice()); BigInteger currentBalance = addressState.getBalance(); boolean canAfford = gasPrice.multiply(feeValue).add(ammountValue).compareTo(currentBalance) != 1; diff --git a/ethereumj-core/src/main/java/org/ethereum/gui/WalletWindow.java b/ethereumj-core/src/main/java/org/ethereum/gui/WalletWindow.java index 0bc23105..7b92ac1d 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/WalletWindow.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/WalletWindow.java @@ -3,6 +3,7 @@ package org.ethereum.gui; import org.ethereum.core.Account; import org.ethereum.core.Wallet; import org.ethereum.manager.MainData; +import org.ethereum.manager.WorldManager; import javax.swing.*; @@ -41,7 +42,7 @@ public class WalletWindow extends JFrame implements Wallet.WalletListener{ Container contentPane = this.getContentPane(); contentPane.setBackground(new Color(255, 255, 255)); - Wallet wallet = MainData.instance.getWallet(); + Wallet wallet = WorldManager.instance.getWallet(); wallet.addListener(this); loadWallet(); @@ -54,7 +55,7 @@ public class WalletWindow extends JFrame implements Wallet.WalletListener{ contentPane.removeAll(); contentPane.setLayout(new FlowLayout()); - Wallet wallet = MainData.instance.getWallet(); + Wallet wallet = WorldManager.instance.getWallet(); for (Account account : wallet.getAccountCollection()){ @@ -76,7 +77,7 @@ public class WalletWindow extends JFrame implements Wallet.WalletListener{ @Override public void mouseClicked(MouseEvent e) { - Wallet wallet = MainData.instance.getWallet(); + Wallet wallet = WorldManager.instance.getWallet(); if (wallet.getAccountCollection().size() >=5){ JOptionPane.showMessageDialog(walletWindow, "Hey do you really need more than 5 address for a demo wallet"); diff --git a/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java b/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java index 87f8e1f1..cd874a94 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java @@ -33,8 +33,6 @@ public class MainData { Logger logger = LoggerFactory.getLogger(getClass().getName()); private List peers = Collections.synchronizedList(new ArrayList()); - private Blockchain blockChain; - private Wallet wallet = new Wallet(); private ClientPeer activePeer; PeerDiscovery peerDiscovery; @@ -42,23 +40,6 @@ public class MainData { public static MainData instance = new MainData(); public MainData() { - // Initialize 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)); - -// wallet.importKey(HashUtil.sha3("cat".getBytes())); - - String secret = CONFIG.coinbaseSecret(); - byte[] cbAddr = HashUtil.sha3(secret.getBytes()); - wallet.importKey(cbAddr); - - - // Initialize Blockchain - blockChain = new Blockchain(wallet); // Initialize PeerData try { @@ -73,13 +54,6 @@ public class MainData { } } - public Blockchain getBlockchain() { - return blockChain; - } - - public Wallet getWallet() { - return wallet; - } public void setActivePeer(ClientPeer peer){ this.activePeer = peer; 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 b410c930..8d9fb743 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/WorldManager.java @@ -1,9 +1,7 @@ package org.ethereum.manager; -import org.ethereum.core.AccountState; -import org.ethereum.core.Block; -import org.ethereum.core.ContractDetails; -import org.ethereum.core.Transaction; +import org.ethereum.core.*; +import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; import org.ethereum.db.DatabaseImpl; import org.ethereum.db.TrackDatabase; @@ -20,6 +18,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static org.ethereum.config.SystemProperties.CONFIG; + /** * * WorldManager is the main class to handle the processing of transactions and managing the world state. @@ -34,7 +34,10 @@ public class WorldManager { private Logger logger = LoggerFactory.getLogger("main"); private Logger stateLogger = LoggerFactory.getLogger("state"); - public static WorldManager instance = new WorldManager(); + + private Blockchain blockChain; + private Wallet wallet = new Wallet(); + private Map pendingTransactions = Collections.synchronizedMap(new HashMap()); @@ -45,10 +48,37 @@ public class WorldManager { public Trie worldState = new Trie(stateDB.getDb()); + public static WorldManager instance = new WorldManager(); + public WorldManager() { + } + + public void loadChain(){ + + // Initialize 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)); + +// wallet.importKey(HashUtil.sha3("cat".getBytes())); + + String secret = CONFIG.coinbaseSecret(); + byte[] cbAddr = HashUtil.sha3(secret.getBytes()); + wallet.importKey(cbAddr); + + + // Initialize Blockchain + blockChain = new Blockchain(wallet); + blockChain.loadChain(); + } + public void applyTransaction(Transaction tx) { // TODO: refactor the wallet transactions to the world manager - MainData.instance.getBlockchain().addWalletTransaction(tx); + if (blockChain != null) + blockChain.addWalletTransaction(tx); // TODO: what is going on with simple wallet transfer @@ -167,7 +197,7 @@ public class WorldManager { byte[] initCode = tx.getData(); Block lastBlock = - MainData.instance.getBlockchain().getLastBlock(); + blockChain.getLastBlock(); ProgramInvoke programInvoke = ProgramInvokeFactory.createProgramInvoke(tx, lastBlock, null, trackDetailDB, trackChainDb, trackStateDB); @@ -191,7 +221,7 @@ public class WorldManager { if (programCode != null && programCode.length != 0){ Block lastBlock = - MainData.instance.getBlockchain().getLastBlock(); + blockChain.getLastBlock(); if (logger.isInfoEnabled()) logger.info("calling for existing contract: addres={}" , Hex.toHexString(tx.getReceiveAddress())); @@ -262,7 +292,7 @@ public class WorldManager { } BigInteger gasPrice = - BigInteger.valueOf( MainData.instance.getBlockchain().getGasPrice()); + BigInteger.valueOf( blockChain.getGasPrice()); BigInteger refund = gasDebit.subtract(BigInteger.valueOf( result.getGasUsed()).multiply(gasPrice)); @@ -306,6 +336,14 @@ public class WorldManager { } } + public Blockchain getBlockChain() { + return blockChain; + } + + public Wallet getWallet() { + return wallet; + } + public void close() { chainDB.close(); stateDB.close(); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/client/EthereumProtocolHandler.java b/ethereumj-core/src/main/java/org/ethereum/net/client/EthereumProtocolHandler.java index 4411fca7..62ffab43 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/client/EthereumProtocolHandler.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/client/EthereumProtocolHandler.java @@ -254,7 +254,7 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter { }, 3000, secToAskForChain * 1000); } - MainData.instance.getBlockchain().addBlocks(blockList); + WorldManager.instance.getBlockChain().addBlocks(blockList); WorldManager.instance.applyBlockList(blockList); if (peerListener != null) peerListener.console(blocksMessage.toString()); } @@ -355,7 +355,7 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter { private void sendGetChain(ChannelHandlerContext ctx){ - byte[] hash = MainData.instance.getBlockchain().getLatestBlockHash(); + byte[] hash = WorldManager.instance.getBlockChain().getLatestBlockHash(); GetChainMessage chainMessage = new GetChainMessage((byte)100, hash); chainMessage.toString(); diff --git a/ethereumj-core/src/main/java/org/ethereum/net/submit/TransactionTask.java b/ethereumj-core/src/main/java/org/ethereum/net/submit/TransactionTask.java index 41266422..6ffc17f6 100644 --- a/ethereumj-core/src/main/java/org/ethereum/net/submit/TransactionTask.java +++ b/ethereumj-core/src/main/java/org/ethereum/net/submit/TransactionTask.java @@ -2,6 +2,7 @@ package org.ethereum.net.submit; import org.ethereum.core.Transaction; import org.ethereum.manager.MainData; +import org.ethereum.manager.WorldManager; import org.ethereum.net.client.ClientPeer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,8 +35,8 @@ public class TransactionTask implements Callable { ClientPeer peer = MainData.instance.getActivePeer(); - WalletTransaction walletTransaction = MainData.instance - .getBlockchain().addWalletTransaction(tx); + WalletTransaction walletTransaction = WorldManager.instance + .getBlockChain().addWalletTransaction(tx); peer.sendTransaction(tx); while(walletTransaction.getApproved() < 1 ){ @@ -45,7 +46,7 @@ public class TransactionTask implements Callable { logger.info("return approved: {}", walletTransaction.getApproved()); } catch (Throwable th) { logger.info("exception caugh: {}", th.getCause()); - MainData.instance.getBlockchain().removeWalletTransaction(tx); + WorldManager.instance.getBlockChain().removeWalletTransaction(tx); } return null; diff --git a/ethereumj-core/src/main/resources/buttons/add-23x23.png b/ethereumj-core/src/main/resources/buttons/add-23x23.png new file mode 100644 index 00000000..f77588dc Binary files /dev/null and b/ethereumj-core/src/main/resources/buttons/add-23x23.png differ