misc
1. PayoutDialog validation 2. Transaction execution after fail bug
This commit is contained in:
parent
04d3492f30
commit
656733985e
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -38,6 +38,8 @@ public class MainData {
|
|||
private Wallet wallet = new Wallet();
|
||||
private ClientPeer activePeer;
|
||||
|
||||
private long gasPrice = 1000;
|
||||
|
||||
private Map<BigInteger, PendingTransaction> pendingTransactions =
|
||||
Collections.synchronizedMap(new HashMap<BigInteger, PendingTransaction>());
|
||||
|
||||
|
@ -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<PeerData> getPeers() {
|
||||
return peers;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
transaction.approve.timeout = 5
|
||||
|
||||
|
|
Loading…
Reference in New Issue