From 656733985e40d1d31773b6823bf04aac245022f7 Mon Sep 17 00:00:00 2001 From: romanman Date: Tue, 27 May 2014 13:29:21 +0300 Subject: [PATCH] misc 1. PayoutDialog validation 2. Transaction execution after fail bug --- .../java/org/ethereum/gui/DialogWorker.java | 2 + .../java/org/ethereum/gui/PayOutDialog.java | 90 +++++++++++++++++-- .../java/org/ethereum/manager/MainData.java | 13 +++ .../ethereum/net/submit/TransactionTask.java | 2 + .../src/main/resources/system.properties | 3 +- 5 files changed, 100 insertions(+), 10 deletions(-) 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 59fdd44d..f0f8907e 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/DialogWorker.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/DialogWorker.java @@ -49,6 +49,8 @@ public class DialogWorker extends SwingWorker { e1.printStackTrace(); dialog.alertStatusMsg("Transaction wasn't approved"); return null; + } finally { + future.cancel(true); } dialog.infoStatusMsg("Transaction got approved"); 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 ce498323..a83d651c 100644 --- a/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java +++ b/ethereumj-core/src/main/java/org/ethereum/gui/PayOutDialog.java @@ -1,5 +1,6 @@ package org.ethereum.gui; +import com.google.common.primitives.Longs; import org.ethereum.core.Transaction; import org.ethereum.manager.MainData; import org.ethereum.net.client.ClientPeer; @@ -19,6 +20,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.regex.Pattern; import javax.swing.*; @@ -36,19 +38,23 @@ class PayOutDialog extends JDialog implements MessageAwareDialog{ AddressState addressState = null; JLabel statusMsg = null; + final JTextField receiverInput; + final JTextField amountInput; + final JTextField feeInput; + public PayOutDialog(Frame parent, final AddressState addressState) { super(parent, "Payout details: ", false); dialog = this; this.addressState = addressState; - final JTextField receiverInput = new JTextField(18); + receiverInput = new JTextField(18); GUIUtils.addStyle(receiverInput, "Pay to:"); - final JTextField amountInput = new JTextField(18); + amountInput = new JTextField(18); GUIUtils.addStyle(amountInput, "Amount: "); - final JTextField feeInput = new JTextField(5); + feeInput = new JTextField(5); GUIUtils.addStyle(feeInput, "Fee: "); this.getContentPane().setBackground(Color.WHITE); @@ -99,11 +105,15 @@ class PayOutDialog extends JDialog implements MessageAwareDialog{ @Override public void mouseClicked(MouseEvent e) { - BigInteger fee = new BigInteger(feeInput.getText()); - BigInteger value = new BigInteger(amountInput.getText()); - byte[] address = Hex.decode(receiverInput.getText()); + if (!validInput()) { + return; + } - // Client + BigInteger fee = new BigInteger(feeInput.getText()); + BigInteger value = new BigInteger(amountInput.getText()); + byte[] address = Hex.decode(receiverInput.getText()); + + // Client ClientPeer peer = MainData.instance.getActivePeer(); if (peer == null) { @@ -114,8 +124,7 @@ class PayOutDialog extends JDialog implements MessageAwareDialog{ byte[] senderPrivKey = addressState.getEcKey().getPrivKeyBytes(); byte[] nonce = addressState.getNonce() == BigInteger.ZERO ? null : addressState.getNonce().toByteArray(); - // todo: in the future it should be retrieved from the block - byte[] gasPrice = new BigInteger("10000000000000").toByteArray(); + byte[] gasPrice = BigInteger.valueOf( MainData.instance.getGasPrice()).toByteArray(); Transaction tx = new Transaction(nonce, gasPrice, BigIntegers .asUnsignedByteArray(fee), address, BigIntegers @@ -143,6 +152,69 @@ class PayOutDialog extends JDialog implements MessageAwareDialog{ this.setResizable(false); } + private boolean validInput() { + + String receiverText = receiverInput.getText(); + if (receiverText == null || receiverText.isEmpty()){ + alertStatusMsg("Should specify valid receiver address"); + return false; + } + + if (!Pattern.matches("[0-9a-fA-F]+", receiverText)){ + alertStatusMsg("Should specify valid receiver address"); + return false; + } + + if (Hex.decode(receiverText).length != 20){ + alertStatusMsg("Should specify valid receiver address"); + return false; + } + + String amountText = amountInput.getText(); + if (amountText == null || amountText.isEmpty()){ + alertStatusMsg("Should specify amount to transfer"); + return false; + } + + if (!Pattern.matches("[0-9]+", amountText)){ + alertStatusMsg("Should specify numeric value for amount "); + return false; + } + + if (amountText.equals("0")){ + alertStatusMsg("Should specify more than zero for transaction"); + return false; + } + + String feeText = feeInput.getText(); + if (feeText == null || feeText.isEmpty()){ + alertStatusMsg("Should specify fee to fund the transaction"); + return false; + } + + if (!Pattern.matches("[0-9]+", feeText)){ + alertStatusMsg("Should specify numeric value for a fee"); + return false; + } + + + // check if the tx is affordable + BigInteger ammountValue = new BigInteger(amountText); + BigInteger feeValue = new BigInteger(feeText); + BigInteger gasPrice = BigInteger.valueOf(MainData.instance.getGasPrice()); + BigInteger currentBalance = addressState.getBalance(); + + boolean canAfford = gasPrice.multiply(feeValue).add(ammountValue).compareTo(currentBalance) != 1; + + if (!canAfford){ + alertStatusMsg("The address can't afford this transaction"); + return false; + } + + + return true; + } + protected JRootPane createRootPane() { Container parent = this.getParent(); 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 ebda286b..81ecec3a 100644 --- a/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java +++ b/ethereumj-core/src/main/java/org/ethereum/manager/MainData.java @@ -38,6 +38,8 @@ public class MainData { private Wallet wallet = new Wallet(); private ClientPeer activePeer; + private long gasPrice = 1000; + private Map pendingTransactions = Collections.synchronizedMap(new HashMap()); @@ -99,6 +101,13 @@ public class MainData { for (int i = blocks.size() - 1; i >= 0 ; --i){ Block block = blocks.get(i); blockChainDB.add(block); + + if (logger.isInfoEnabled()) + logger.info("block added to the chain hash: {}", Hex.toHexString(block.getHash())); + + this.gasPrice = block.getMinGasPrice(); + + wallet.processBlock(block); } @@ -158,6 +167,10 @@ public class MainData { return pendingTransaction; } + public long getGasPrice() { + return gasPrice; + } + public List getPeers() { return peers; } 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 94336b09..6e7d2ee7 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 @@ -21,6 +21,7 @@ public class TransactionTask implements Callable { Logger logger = LoggerFactory.getLogger("TransactionTask"); Transaction tx; + boolean obsolete = false; public TransactionTask(Transaction tx) { @@ -48,4 +49,5 @@ public class TransactionTask implements Callable { return null; } + } diff --git a/ethereumj-core/src/main/resources/system.properties b/ethereumj-core/src/main/resources/system.properties index 5bac643c..4aca913e 100644 --- a/ethereumj-core/src/main/resources/system.properties +++ b/ethereumj-core/src/main/resources/system.properties @@ -34,4 +34,5 @@ peer.discovery.timeout = 2 # transaction got approved when # include into a transactions msg # retrieved from the peer [seconds] -transaction.approve.timeout = 5 \ No newline at end of file +transaction.approve.timeout = 5 +