diff --git a/convex-gui/src/main/java/convex/gui/components/FilePicker.java b/convex-gui/src/main/java/convex/gui/components/FilePicker.java new file mode 100644 index 000000000..f21b42746 --- /dev/null +++ b/convex-gui/src/main/java/convex/gui/components/FilePicker.java @@ -0,0 +1,44 @@ +package convex.gui.components; + +import java.awt.event.ActionEvent; + +import javax.swing.JButton; +import javax.swing.JFileChooser; +import javax.swing.JPanel; +import javax.swing.JTextField; + +import net.miginfocom.swing.MigLayout; + +@SuppressWarnings("serial") +public class FilePicker extends JPanel { + + private String fileName; + + private JTextField fileField; + private JButton button; + + private JFileChooser fileChooser; + + + public FilePicker(String filename) { + this.fileName=filename; + + this.fileChooser=new JFileChooser(); + + setLayout(new MigLayout()); + + fileField=new JTextField(fileName); + add(fileField); + + button=new JButton("..."); + button.addActionListener(this::selectFile); + add(button); + } + + public void selectFile(ActionEvent e) { + int selected=fileChooser.showDialog(this, "Select"); + if (selected==JFileChooser.APPROVE_OPTION) { + fileField.setText(fileChooser.getSelectedFile().getAbsolutePath()); + } + } +} diff --git a/convex-gui/src/main/java/convex/gui/peer/PeerGUI.java b/convex-gui/src/main/java/convex/gui/peer/PeerGUI.java index 41800966b..d852f207f 100644 --- a/convex-gui/src/main/java/convex/gui/peer/PeerGUI.java +++ b/convex-gui/src/main/java/convex/gui/peer/PeerGUI.java @@ -77,12 +77,12 @@ public static void main(String[] args) throws Exception { // call to set up Look and Feel Toolkit.init(); - PeerGUI gui=launchPeerGUI(DEFAULT_NUM_PEERS, AKeyPair.generate(),true); + PeerGUI gui=launchPeerGUI(DEFAULT_NUM_PEERS, AKeyPair.generate()); gui.waitForClose(); System.exit(0); } - public static PeerGUI launchPeerGUI(int peerNum, AKeyPair genesisKey, boolean topLevel) throws InterruptedException, PeerException { + public static PeerGUI launchPeerGUI(int peerNum, AKeyPair genesisKey) throws InterruptedException, PeerException { PeerGUI manager = create(peerNum,genesisKey); manager.run(); return manager; @@ -101,6 +101,17 @@ public static PeerGUI launchPeerGUI(InetSocketAddress sa, AWalletEntry we) throw manager.run(); return manager; } + + public static PeerGUI launchPeerGUI(Server server) throws InterruptedException, PeerException { + DefaultListModel peerList=new DefaultListModel<>(); + + server.launch(); + ConvexLocal convex=ConvexLocal.connect(server); + peerList.addElement(convex); + PeerGUI manager = new PeerGUI(peerList); + manager.run(); + return manager; + } public static PeerGUI create(int peerCount, AKeyPair genesisKey) throws PeerException { DefaultListModel peerList=launchAllPeers(peerCount,genesisKey); @@ -127,7 +138,16 @@ private static DefaultListModel launchAllPeers(int peerCount, AKeyP DefaultListModel peerList=new DefaultListModel<>(); List serverList = API.launchLocalPeers(KEYPAIRS,genesisState); for (Server server: serverList) { - ConvexLocal convex=Convex.connect(server, server.getPeerController(), server.getControllerKey()); + Address controller=server.getPeerController(); + AKeyPair kp=server.getControllerKey(); + ConvexLocal convex=Convex.connect(server, controller, kp); + + if (kp==null) { + // Try to find alternative controller key in key ring if available + kp=KeyRingPanel.findWalletEntry(convex).getKeyPair(); + convex.setKeyPair(kp); + } + peerList.addElement(convex); // initial wallet list @@ -314,7 +334,7 @@ public ConvexLocal getDefaultConvex() { ConvexLocal c= peerList.get(i); if (c.getLocalServer().isLive()) return c; } - throw new IllegalStateException("No live peers!"); + throw new IllegalStateException("No live peers we control!"); } public Convex getClientConvex(Address contract) { @@ -384,20 +404,20 @@ public Server getPrimaryServer() { } - public void launchExtraPeer() { + public void launchExtraPeer(ConvexLocal source) { AKeyPair kp=AKeyPair.generate(); try { - Server base=getPrimaryServer(); - ConvexLocal convex=getDefaultConvex(); - Address a= convex.createAccountSync(kp.getAccountKey()); - long amt=convex.getBalance()/10; - convex.transferSync(a, amt); + Server base=source.getLocalServer(); + + Address a= source.createAccountSync(kp.getAccountKey()); + long amt=source.getBalance()/10; + source.transferSync(a, amt); KeyRingPanel.addWalletEntry(HotWalletEntry.create(kp,"Generated peer key")); // Set up Peer in base server - convex=Convex.connect(base, a, kp); + ConvexLocal convex=Convex.connect(base, a, kp); AccountKey key=kp.getAccountKey(); Result rcr=convex.transactSync("(create-peer "+key+" "+amt/2+")"); if (rcr.isError()) { diff --git a/convex-gui/src/main/java/convex/gui/peer/PeerLaunchDialog.java b/convex-gui/src/main/java/convex/gui/peer/PeerLaunchDialog.java index 5366731a6..ea5e75368 100644 --- a/convex-gui/src/main/java/convex/gui/peer/PeerLaunchDialog.java +++ b/convex-gui/src/main/java/convex/gui/peer/PeerLaunchDialog.java @@ -15,6 +15,8 @@ import convex.core.crypto.AKeyPair; import convex.core.crypto.wallet.AWalletEntry; import convex.core.crypto.wallet.HotWalletEntry; +import convex.core.util.FileUtils; +import convex.gui.components.FilePicker; import convex.gui.components.HostCombo; import convex.gui.components.Toast; import convex.gui.components.account.KeyPairCombo; @@ -73,6 +75,12 @@ public static void runLaunchDialog(JComponent parent) { joinPanel.add(peerKeyField); joinPanel.add(Toolkit.makeHelp("Select peer key for the new peer.")); + joinPanel.add(new JLabel("Etch Store: ")); + FilePicker filePicker=new FilePicker(FileUtils.getFile("~/.convex/etch.db").getAbsolutePath()); + joinPanel.add(filePicker); + joinPanel.add(Toolkit.makeHelp("Select Etch database file for peer operation.")); + + JTabbedPane tabs=new JTabbedPane(); tabs.add(testNetPanel,"Local Testnet"); tabs.add(joinPanel,"Join Network"); @@ -98,7 +106,7 @@ public static void runLaunchDialog(JComponent parent) { } AKeyPair kp=we.getKeyPair(); - PeerGUI.launchPeerGUI(numPeers, kp,false); + PeerGUI.launchPeerGUI(numPeers, kp); } else if (tabs.getSelectedComponent()==joinPanel) { String host=hostField.getText(); InetSocketAddress sa=IPUtils.toInetSocketAddress(host); diff --git a/convex-gui/src/main/java/convex/gui/peer/ServerListPanel.java b/convex-gui/src/main/java/convex/gui/peer/ServerListPanel.java index d09dcb4bd..21621a874 100644 --- a/convex-gui/src/main/java/convex/gui/peer/ServerListPanel.java +++ b/convex-gui/src/main/java/convex/gui/peer/ServerListPanel.java @@ -66,7 +66,10 @@ public ServerListPanel(PeerGUI manager) { JPanel toolBar = new ActionPanel(); add(toolBar, BorderLayout.SOUTH); - ActionButton btnLaunch = new ActionButton("Launch!",0xeb9b,e -> manager.launchExtraPeer()); + ActionButton btnLaunch = new ActionButton("Launch!",0xeb9b,e -> { + ConvexLocal convex=manager.getDefaultConvex(); + manager.launchExtraPeer(convex); + }); btnLaunch.setToolTipText("Launch an extra peer for the network. Allocates some stake from genesis account"); toolBar.add(btnLaunch); diff --git a/convex-peer/src/main/java/convex/peer/Server.java b/convex-peer/src/main/java/convex/peer/Server.java index 5cd4fc0c5..4b9e84e82 100644 --- a/convex-peer/src/main/java/convex/peer/Server.java +++ b/convex-peer/src/main/java/convex/peer/Server.java @@ -328,7 +328,9 @@ public String getHostname() { * Launch the Peer Server, including all main server threads * @throws InterruptedException */ - public void launch() throws LaunchException, InterruptedException { + public synchronized void launch() throws LaunchException, InterruptedException { + if (isRunning) return; // in case of double launch + isRunning=true; AStore savedStore=Stores.current(); try { Stores.setCurrent(store); @@ -740,7 +742,7 @@ public void setHostname(String string) { /** * Flag for a running server. Setting to false will terminate server threads. */ - private volatile boolean isRunning = true; + private volatile boolean isRunning = false; /** * Flag for a live server. Live Server has synced with at least one other peer