mirror of
https://github.com/status-im/ethereumj-personal.git
synced 2025-01-12 12:54:49 +00:00
PendingTransaction mechanism introduced:
1. the dialog put a pending transaction on the list 2. the dialog send the transaction to a net 3. wherever the transaction got for the wire in will change to approve state 4. only after the approve a Wallet state changes 5. After the block is received with that tx the pending been clean up
This commit is contained in:
parent
0c01a4fde6
commit
dbbfe450e5
@ -62,6 +62,13 @@ public class SystemProperties {
|
|||||||
return Integer.parseInt(prop.getProperty("peer.discovery.timeout")) * 1000;
|
return Integer.parseInt(prop.getProperty("peer.discovery.timeout")) * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int transactionApproveTimeout(){
|
||||||
|
if (prop.isEmpty())
|
||||||
|
return 10;
|
||||||
|
return Integer.parseInt(prop.getProperty("transaction.approve.timeout"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public String clientName() {
|
public String clientName() {
|
||||||
if(prop.isEmpty()) return "";
|
if(prop.isEmpty()) return "";
|
||||||
return prop.getProperty("client.name");
|
return prop.getProperty("client.name");
|
||||||
|
@ -12,6 +12,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.spongycastle.util.BigIntegers;
|
import org.spongycastle.util.BigIntegers;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@ -39,6 +39,8 @@ public class Wallet {
|
|||||||
|
|
||||||
private List<WalletListener> listeners = new ArrayList<WalletListener>();
|
private List<WalletListener> listeners = new ArrayList<WalletListener>();
|
||||||
|
|
||||||
|
private HashMap<BigInteger, Transaction> transactionMap = new HashMap<BigInteger, Transaction>();
|
||||||
|
|
||||||
public void addNewKey(){
|
public void addNewKey(){
|
||||||
|
|
||||||
AddressState addressState = new AddressState();
|
AddressState addressState = new AddressState();
|
||||||
@ -86,31 +88,45 @@ public class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void applyTransaction(Transaction transaction){
|
||||||
|
|
||||||
|
transactionMap.put(new BigInteger(transaction.getHash()), transaction );
|
||||||
|
|
||||||
|
byte[] senderAddress = transaction.getSender();
|
||||||
|
AddressState senderState = rows.get(Hex.toHexString(senderAddress));
|
||||||
|
if (senderState != null){
|
||||||
|
|
||||||
|
BigInteger value = new BigInteger(transaction.getValue());
|
||||||
|
senderState.addToBalance(value.negate());
|
||||||
|
senderState.incrementTheNonce();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] receiveAddress = transaction.getReceiveAddress();
|
||||||
|
AddressState receiverState = rows.get(Hex.toHexString(receiveAddress));
|
||||||
|
if (receiverState != null){
|
||||||
|
receiverState.addToBalance(new BigInteger(1, transaction.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void processBlock(Block block){
|
public void processBlock(Block block){
|
||||||
|
|
||||||
boolean walletUpdated = false;
|
|
||||||
// todo: proceed coinbase when you are the miner that gets an award
|
// todo: proceed coinbase when you are the miner that gets an award
|
||||||
|
|
||||||
|
boolean walletUpdated = false;
|
||||||
|
|
||||||
List<Transaction> transactions = block.getTransactionsList();
|
List<Transaction> transactions = block.getTransactionsList();
|
||||||
|
|
||||||
for (Transaction tx : transactions){
|
for (Transaction tx : transactions){
|
||||||
|
|
||||||
|
boolean txExist = transactionMap.get(new BigInteger(tx.getHash())) != null;
|
||||||
|
if (txExist) break;
|
||||||
|
|
||||||
byte[] senderAddress = tx.getSender();
|
else {
|
||||||
AddressState senderState = rows.get(Hex.toHexString(senderAddress));
|
|
||||||
if (senderState != null){
|
|
||||||
BigInteger value = new BigInteger(tx.getValue());
|
|
||||||
|
|
||||||
senderState.addToBalance(value.negate());
|
applyTransaction(tx);
|
||||||
|
|
||||||
senderState.incrementTheNonce();
|
|
||||||
walletUpdated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] receiveAddress = tx.getReceiveAddress();
|
|
||||||
AddressState receiverState = rows.get(Hex.toHexString(receiveAddress));
|
|
||||||
if (receiverState != null){
|
|
||||||
receiverState.addToBalance(new BigInteger(1, tx.getValue()));
|
|
||||||
walletUpdated = true;
|
walletUpdated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ public class ConnectionConsoleWindow extends JFrame implements PeerListener{
|
|||||||
// new ClientPeer(thisConsole).connect("54.201.28.117", 30303);
|
// new ClientPeer(thisConsole).connect("54.201.28.117", 30303);
|
||||||
|
|
||||||
// Peer Server One: peer discovery
|
// Peer Server One: peer discovery
|
||||||
new ClientPeer(thisConsole).connect("54.204.10.41", 30303);
|
// new ClientPeer(thisConsole).connect("54.204.10.41", 30303);
|
||||||
|
|
||||||
// Some dude in Canada
|
// Some dude in Canada
|
||||||
// new ClientPeer(thisConsole).connect("131.104.247.135", 30303);
|
// new ClientPeer(thisConsole).connect("131.104.247.135", 30303);
|
||||||
@ -85,7 +85,7 @@ public class ConnectionConsoleWindow extends JFrame implements PeerListener{
|
|||||||
// new ClientPeer(thisConsole).connect("54.204.10.41", 30303);
|
// new ClientPeer(thisConsole).connect("54.204.10.41", 30303);
|
||||||
|
|
||||||
// RomanJ
|
// RomanJ
|
||||||
// new ClientPeer(thisConsole).connect("54.211.14.10", 40404);
|
new ClientPeer(thisConsole).connect("54.211.14.10", 40404);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
t.start();
|
t.start();
|
||||||
|
@ -28,4 +28,38 @@ public class GUIUtils {
|
|||||||
textField.setForeground(new Color(143, 170, 220));
|
textField.setForeground(new Color(143, 170, 220));
|
||||||
textField.setFont(new Font("Monospaced", 0, 13));
|
textField.setFont(new Font("Monospaced", 0, 13));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void addStyle(JTextArea textArea, String labelName, boolean isBorder){
|
||||||
|
|
||||||
|
Border border = null;
|
||||||
|
if (isBorder) {
|
||||||
|
Border line = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
|
||||||
|
TitledBorder titled = BorderFactory.createTitledBorder(line, labelName);
|
||||||
|
titled.setTitleFont(new Font("Verdana", 0, 13));
|
||||||
|
titled.setTitleColor(new Color(213, 225, 185));
|
||||||
|
Border empty = new EmptyBorder(5, 8, 5, 8);
|
||||||
|
CompoundBorder cBorder = new CompoundBorder(titled, empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
textArea.setBorder(border);
|
||||||
|
textArea.setForeground(new Color(143, 170, 220));
|
||||||
|
textArea.setFont(new Font("Monospaced", 0, 13));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addStyle(JScrollPane jScrollPane, String labelName){
|
||||||
|
Border line = BorderFactory.createLineBorder(Color.LIGHT_GRAY);
|
||||||
|
TitledBorder titled = BorderFactory.createTitledBorder(line, labelName);
|
||||||
|
titled.setTitleFont(new Font("Verdana", 0, 13));
|
||||||
|
titled.setTitleColor(new Color(213, 225, 185));
|
||||||
|
Border empty = new EmptyBorder(5, 8, 5, 8);
|
||||||
|
CompoundBorder border = new CompoundBorder(titled, empty);
|
||||||
|
jScrollPane.setBorder(border);
|
||||||
|
jScrollPane.setForeground(new Color(143, 170, 220));
|
||||||
|
jScrollPane.setBackground(Color.WHITE);
|
||||||
|
jScrollPane.setFont(new Font("Monospaced", 0, 13));
|
||||||
|
jScrollPane.setHorizontalScrollBar(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
package org.ethereum.gui;
|
package org.ethereum.gui;
|
||||||
|
|
||||||
|
import org.ethereum.config.SystemProperties;
|
||||||
import org.ethereum.core.Transaction;
|
import org.ethereum.core.Transaction;
|
||||||
import org.ethereum.manager.MainData;
|
import org.ethereum.manager.MainData;
|
||||||
import org.ethereum.net.client.ClientPeer;
|
import org.ethereum.net.client.ClientPeer;
|
||||||
|
import org.ethereum.net.submit.TransactionExecutor;
|
||||||
|
import org.ethereum.net.submit.TransactionTask;
|
||||||
import org.ethereum.wallet.AddressState;
|
import org.ethereum.wallet.AddressState;
|
||||||
import org.spongycastle.util.BigIntegers;
|
import org.spongycastle.util.BigIntegers;
|
||||||
import org.spongycastle.util.encoders.Hex;
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
import samples.Main;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
@ -14,12 +18,20 @@ import java.awt.event.MouseAdapter;
|
|||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.Border;
|
import javax.swing.border.Border;
|
||||||
import javax.swing.border.CompoundBorder;
|
import javax.swing.border.CompoundBorder;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
|
|
||||||
|
import static org.ethereum.config.SystemProperties.CONFIG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* www.ethereumJ.com
|
* www.ethereumJ.com
|
||||||
* User: Roman Mandeleil
|
* User: Roman Mandeleil
|
||||||
@ -83,7 +95,6 @@ class PayOutDialog extends JDialog {
|
|||||||
}}
|
}}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
URL approveIconURL = ClassLoader.getSystemResource("buttons/approve.png");
|
URL approveIconURL = ClassLoader.getSystemResource("buttons/approve.png");
|
||||||
ImageIcon approveIcon = new ImageIcon(approveIconURL);
|
ImageIcon approveIcon = new ImageIcon(approveIconURL);
|
||||||
JLabel approveLabel = new JLabel(approveIcon);
|
JLabel approveLabel = new JLabel(approveIcon);
|
||||||
@ -94,7 +105,6 @@ class PayOutDialog extends JDialog {
|
|||||||
this.getContentPane().add(approveLabel);
|
this.getContentPane().add(approveLabel);
|
||||||
approveLabel.setVisible(true);
|
approveLabel.setVisible(true);
|
||||||
|
|
||||||
|
|
||||||
approveLabel.addMouseListener(
|
approveLabel.addMouseListener(
|
||||||
new MouseAdapter() {
|
new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
@ -131,17 +141,18 @@ class PayOutDialog extends JDialog {
|
|||||||
tx.sign(senderPrivKey);
|
tx.sign(senderPrivKey);
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
|
|
||||||
// todo something if sign fails
|
dialog.alertStatusMsg("Failed to sign the transaction");
|
||||||
e1.printStackTrace();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
peer.sendTransaction(tx);
|
// SwingWorker
|
||||||
dialog.infoStatusMsg("Transaction sent to the network, waiting for approve");
|
|
||||||
|
DialogWorker worker = new DialogWorker(tx);
|
||||||
|
worker.execute();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
feeInput.setText("1000");
|
feeInput.setText("1000");
|
||||||
amountInput.setText("0");
|
amountInput.setText("0");
|
||||||
|
|
||||||
@ -178,14 +189,69 @@ class PayOutDialog extends JDialog {
|
|||||||
return rootPane;
|
return rootPane;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void infoStatusMsg(String text){
|
public void infoStatusMsg(final String text){
|
||||||
this.statusMsg.setForeground(Color.GREEN.darker().darker());
|
|
||||||
this.statusMsg.setText(text);
|
final PayOutDialog dialog = this;
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
dialog.statusMsg.setForeground(Color.GREEN.darker().darker());
|
||||||
|
dialog.statusMsg.setText(text);
|
||||||
|
dialog.revalidate();
|
||||||
|
dialog.repaint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void alertStatusMsg(String text){
|
public void alertStatusMsg(final String text){
|
||||||
this.statusMsg.setForeground(Color.RED);
|
final PayOutDialog dialog = this;
|
||||||
this.statusMsg.setText(text);
|
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
dialog.statusMsg.setForeground(Color.RED);
|
||||||
|
dialog.statusMsg.setText(text);
|
||||||
|
dialog.revalidate();
|
||||||
|
dialog.repaint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DialogWorker extends SwingWorker{
|
||||||
|
|
||||||
|
Transaction tx;
|
||||||
|
|
||||||
|
DialogWorker(Transaction tx) {
|
||||||
|
this.tx = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Object doInBackground() throws Exception {
|
||||||
|
TransactionTask transactionTask = new TransactionTask(tx);
|
||||||
|
Future future = TransactionExecutor.instance.submitTransaction(transactionTask);
|
||||||
|
dialog.infoStatusMsg("Transaction sent to the network, waiting for approve");
|
||||||
|
|
||||||
|
try {
|
||||||
|
future.get(CONFIG.transactionApproveTimeout(), TimeUnit.SECONDS);
|
||||||
|
} catch (TimeoutException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
dialog.alertStatusMsg("Transaction wasn't approved, network timeout");
|
||||||
|
return null;
|
||||||
|
} catch (InterruptedException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
dialog.alertStatusMsg("Transaction wasn't approved");
|
||||||
|
return null;
|
||||||
|
} catch (ExecutionException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
dialog.alertStatusMsg("Transaction wasn't approved");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.infoStatusMsg("Transaction got approved");
|
||||||
|
MainData.instance.getWallet().applyTransaction(tx);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
package org.ethereum.manager;
|
package org.ethereum.manager;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.maxmind.geoip.Location;
|
import com.maxmind.geoip.Location;
|
||||||
import org.ethereum.core.Block;
|
import org.ethereum.core.Block;
|
||||||
@ -18,7 +15,10 @@ import org.ethereum.net.client.ClientPeer;
|
|||||||
import org.ethereum.net.client.PeerData;
|
import org.ethereum.net.client.PeerData;
|
||||||
import org.ethereum.net.message.StaticMessages;
|
import org.ethereum.net.message.StaticMessages;
|
||||||
import org.ethereum.net.peerdiscovery.PeerDiscovery;
|
import org.ethereum.net.peerdiscovery.PeerDiscovery;
|
||||||
|
import org.ethereum.net.submit.PendingTransaction;
|
||||||
import org.ethereum.wallet.AddressState;
|
import org.ethereum.wallet.AddressState;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.spongycastle.util.encoders.Hex;
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,11 +28,16 @@ import org.spongycastle.util.encoders.Hex;
|
|||||||
*/
|
*/
|
||||||
public class MainData {
|
public class MainData {
|
||||||
|
|
||||||
|
Logger logger = LoggerFactory.getLogger(getClass().getName());
|
||||||
|
|
||||||
private List<PeerData> peers = Collections.synchronizedList(new ArrayList<PeerData>());
|
private List<PeerData> peers = Collections.synchronizedList(new ArrayList<PeerData>());
|
||||||
private List<Block> blockChainDB = new ArrayList<Block>();
|
private List<Block> blockChainDB = new ArrayList<Block>();
|
||||||
private Wallet wallet = new Wallet();
|
private Wallet wallet = new Wallet();
|
||||||
private ClientPeer activePeer;
|
private ClientPeer activePeer;
|
||||||
|
|
||||||
|
private Map<BigInteger, PendingTransaction> pendingTransactions =
|
||||||
|
Collections.synchronizedMap(new HashMap<BigInteger, PendingTransaction>());
|
||||||
|
|
||||||
PeerDiscovery peerDiscovery;
|
PeerDiscovery peerDiscovery;
|
||||||
|
|
||||||
public static MainData instance = new MainData();
|
public static MainData instance = new MainData();
|
||||||
@ -67,7 +72,6 @@ public class MainData {
|
|||||||
// check that the parent is the genesis
|
// check that the parent is the genesis
|
||||||
if (blockChainDB.isEmpty() &&
|
if (blockChainDB.isEmpty() &&
|
||||||
!Arrays.equals(StaticMessages.GENESIS_HASH, firstBlockToAdd.getParentHash())){
|
!Arrays.equals(StaticMessages.GENESIS_HASH, firstBlockToAdd.getParentHash())){
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +90,16 @@ public class MainData {
|
|||||||
wallet.processBlock(block);
|
wallet.processBlock(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("*** Block chain size: [" + blockChainDB.size() + "]");
|
// Remove all pending transactions as they already approved by the net
|
||||||
|
for (Block block : blocks){
|
||||||
|
for (Transaction tx : block.getTransactionsList()){
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("pending cleanup: tx.hash: [{}]", Hex.toHexString( tx.getHash()));
|
||||||
|
pendingTransactions.remove(tx.getHash());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info("*** Block chain size: [ {} ]", blockChainDB.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getLatestBlockHash(){
|
public byte[] getLatestBlockHash(){
|
||||||
@ -113,18 +126,28 @@ public class MainData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* todo: here will be all the pending transaction approve
|
/*
|
||||||
* 1) the dialog put a pending transaction her
|
* 1) the dialog put a pending transaction on the list
|
||||||
* 2) the dialog send the transaction to a net
|
* 2) the dialog send the transaction to a net
|
||||||
* 3) wherever the transaction got for the wire in will change to approve state
|
* 3) wherever the transaction got for the wire in will change to approve state
|
||||||
* 4) only after the approve a) Wallet state changes
|
* 4) only after the approve a) Wallet state changes
|
||||||
*
|
*
|
||||||
* 5) After the block is received with that tx the pending been clean up
|
* 5) After the block is received with that tx the pending been clean up
|
||||||
*/
|
*/
|
||||||
public void addTransactions(List<Transaction> transactions) {
|
public PendingTransaction addPendingTransaction(Transaction transaction) {
|
||||||
|
|
||||||
|
BigInteger hash = new BigInteger(transaction.getHash());
|
||||||
|
|
||||||
|
PendingTransaction pendingTransaction = pendingTransactions.get(hash);
|
||||||
|
if (pendingTransaction != null)
|
||||||
|
pendingTransaction.incApproved();
|
||||||
|
else{
|
||||||
|
|
||||||
|
pendingTransaction = new PendingTransaction(transaction);
|
||||||
|
pendingTransactions.put(hash, pendingTransaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pendingTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PeerData> getPeers() {
|
public List<PeerData> getPeers() {
|
||||||
|
@ -12,6 +12,7 @@ import java.util.Timer;
|
|||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
import org.ethereum.core.Block;
|
import org.ethereum.core.Block;
|
||||||
|
import org.ethereum.core.Transaction;
|
||||||
import org.ethereum.gui.PeerListener;
|
import org.ethereum.gui.PeerListener;
|
||||||
import org.ethereum.manager.MainData;
|
import org.ethereum.manager.MainData;
|
||||||
import org.ethereum.net.Command;
|
import org.ethereum.net.Command;
|
||||||
@ -200,9 +201,10 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
RLPList rlpList = RLP.decode2(payload);
|
RLPList rlpList = RLP.decode2(payload);
|
||||||
TransactionsMessage transactionsMessage = new TransactionsMessage(rlpList);
|
TransactionsMessage transactionsMessage = new TransactionsMessage(rlpList);
|
||||||
MainData.instance.addTransactions(transactionsMessage.getTransactions());
|
for (Transaction tx : transactionsMessage.getTransactions())
|
||||||
|
MainData.instance.addPendingTransaction(tx);
|
||||||
|
|
||||||
// todo: if you got transactions send it to your peers
|
// todo: if you got transactions send it to your connected peers
|
||||||
logger.info(transactionsMessage.toString());
|
logger.info(transactionsMessage.toString());
|
||||||
if (peerListener != null) peerListener.console(transactionsMessage.toString());
|
if (peerListener != null) peerListener.console(transactionsMessage.toString());
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package org.ethereum.net.submit;
|
||||||
|
|
||||||
|
import org.ethereum.core.Transaction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* www.ethereumJ.com
|
||||||
|
* User: Roman Mandeleil
|
||||||
|
* Created on: 23/05/2014 18:41
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class PendingTransaction {
|
||||||
|
|
||||||
|
Transaction tx;
|
||||||
|
int approved = 0; // each time the tx got from the wire this value increased
|
||||||
|
|
||||||
|
public PendingTransaction(Transaction tx) {
|
||||||
|
this.tx = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incApproved(){++this.approved;}
|
||||||
|
|
||||||
|
public int getApproved() {
|
||||||
|
return approved;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
|||||||
|
package org.ethereum.net.submit;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* www.ethereumJ.com
|
||||||
|
* User: Roman Mandeleil
|
||||||
|
* Created on: 23/05/2014 19:07
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TransactionExecutor {
|
||||||
|
|
||||||
|
static {instance = new TransactionExecutor();}
|
||||||
|
public static TransactionExecutor instance;
|
||||||
|
|
||||||
|
ExecutorService executor = Executors.newFixedThreadPool(1);
|
||||||
|
|
||||||
|
public Future submitTransaction(TransactionTask task){
|
||||||
|
return executor.submit(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package org.ethereum.net.submit;
|
||||||
|
|
||||||
|
import org.ethereum.core.Transaction;
|
||||||
|
import org.ethereum.manager.MainData;
|
||||||
|
import org.ethereum.net.client.ClientPeer;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import static java.lang.Thread.sleep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* www.ethereumJ.com
|
||||||
|
* User: Roman Mandeleil
|
||||||
|
* Created on: 23/05/2014 18:33
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TransactionTask implements Callable {
|
||||||
|
|
||||||
|
Logger logger = LoggerFactory.getLogger("TransactionTask");
|
||||||
|
|
||||||
|
Transaction tx;
|
||||||
|
|
||||||
|
|
||||||
|
public TransactionTask(Transaction tx) {
|
||||||
|
this.tx = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object call() throws Exception {
|
||||||
|
|
||||||
|
logger.info("call() tx: {}", tx.toString());
|
||||||
|
|
||||||
|
ClientPeer peer = MainData.instance.getActivePeer();
|
||||||
|
|
||||||
|
PendingTransaction pendingTransaction = MainData.instance.addPendingTransaction(tx);
|
||||||
|
peer.sendTransaction(tx);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while(pendingTransaction.getApproved() < 1 ){
|
||||||
|
|
||||||
|
++i;
|
||||||
|
sleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("return approved: {}", pendingTransaction.getApproved());
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
# Root logger option
|
# Root logger option
|
||||||
log4j.rootLogger=INFO, stdout
|
log4j.rootLogger=DEBUG, stdout
|
||||||
|
|
||||||
# Direct log messages to stdout
|
# Direct log messages to stdout
|
||||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||||
|
@ -27,3 +27,10 @@ peer.discovery.workers = 5
|
|||||||
# connection timeout for trying to
|
# connection timeout for trying to
|
||||||
# connect to a peer [seconds]
|
# connect to a peer [seconds]
|
||||||
peer.discovery.timeout = 3
|
peer.discovery.timeout = 3
|
||||||
|
|
||||||
|
# the time we wait to the network
|
||||||
|
# to approve the transaction, the
|
||||||
|
# transaction got approved when
|
||||||
|
# include into a transactions msg
|
||||||
|
# retrieved from the peer [seconds]
|
||||||
|
transaction.approve.timeout = 3
|
Loading…
x
Reference in New Issue
Block a user