Skip to content

Commit 43286e4

Browse files
committed
Add convex peer backup CLI command
1 parent 647ab20 commit 43286e4

File tree

7 files changed

+116
-29
lines changed

7 files changed

+116
-29
lines changed

convex-cli/src/main/java/convex/cli/mixins/EtchMixin.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
import java.io.File;
44
import java.io.IOException;
5+
import java.util.List;
56

67
import convex.cli.CLIError;
78
import convex.cli.Constants;
9+
import convex.core.data.AccountKey;
810
import convex.core.util.FileUtils;
911
import convex.etch.EtchStore;
12+
import convex.peer.API;
1013
import picocli.CommandLine.Option;
1114
import picocli.CommandLine.ScopeType;
1215

@@ -46,4 +49,15 @@ public synchronized EtchStore getEtchStore(String fileName) {
4649
public EtchStore getEtchStore() {
4750
return getEtchStore(etchStoreFilename);
4851
}
52+
53+
public List<AccountKey> getPeerList() {
54+
EtchStore etchStore=getEtchStore();
55+
56+
try {
57+
List<AccountKey> keys=API.listPeers(getEtchStore());
58+
return keys;
59+
} catch (IOException e) {
60+
throw new CLIError("Unable to list peers in store: "+etchStore);
61+
}
62+
}
4963
}

convex-cli/src/main/java/convex/cli/mixins/PeerKeyMixin.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
55

6+
import convex.core.data.AccountKey;
67
import picocli.CommandLine.Option;
78
import picocli.CommandLine.ScopeType;
89

@@ -58,4 +59,12 @@ public char[] getKeyPassword() {
5859
}
5960
return keypass;
6061
}
62+
63+
public AccountKey getAcountKey() {
64+
String ks=getPublicKey();
65+
AccountKey result= AccountKey.parse(ks);
66+
return result;
67+
}
68+
69+
6170
}

convex-cli/src/main/java/convex/cli/peer/Peer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
PeerCreate.class,
2121
PeerStart.class,
2222
PeerList.class,
23+
PeerBackup.class,
2324
PeerGenesis.class,
2425
Help.class
2526
},
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package convex.cli.peer;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.util.List;
6+
7+
import convex.cli.CLIError;
8+
import convex.core.data.ACell;
9+
import convex.core.data.AMap;
10+
import convex.core.data.AccountKey;
11+
import convex.core.data.Keyword;
12+
import convex.core.util.FileUtils;
13+
import convex.core.util.Utils;
14+
import picocli.CommandLine.Command;
15+
import picocli.CommandLine.Option;
16+
17+
@Command(
18+
name = "backup",
19+
mixinStandardHelpOptions = true,
20+
description = "Backup stored data for a peer")
21+
public class PeerBackup extends APeerCommand {
22+
23+
@Option(names = { "--output-file" },
24+
description = "Output file for peer CAD3 data. Defaults to timestamped CAD3 file.")
25+
private String outFile;
26+
27+
28+
@SuppressWarnings("resource")
29+
@Override
30+
protected void execute() throws InterruptedException {
31+
32+
AccountKey k= peerKeyMixin.getAcountKey();
33+
34+
if (k==null) {
35+
List<AccountKey> peerList=etchMixin.getPeerList();
36+
int n=peerList.size();
37+
if (n==0) {
38+
throw new CLIError("No peers available in store: "+etchMixin.getEtchStore());
39+
}
40+
41+
String s=peerKeyMixin.getPublicKey();
42+
if (s!=null) {
43+
peerList.removeIf(pk->!pk.toHexString().startsWith(s));
44+
n=peerList.size();
45+
}
46+
47+
if (n==0) {
48+
throw new CLIError("No peer in store with prefix: "+s);
49+
} if (n==1) {
50+
k=peerList.get(0);
51+
} else if (n==0) {
52+
throw new CLIError("No peers available in store: "+etchMixin.getEtchStore());
53+
} else {
54+
informWarning("Need to select peer to backup, available peers are:");
55+
for (AccountKey pk: peerList) {
56+
inform(pk.toHexString());
57+
}
58+
59+
throw new CLIError("Please specify which peer to backup with --peer-key");
60+
}
61+
}
62+
63+
AMap<Keyword,ACell> peerData;
64+
try {
65+
peerData=convex.core.cvm.Peer.getPeerData(etchMixin.getEtchStore(), k);
66+
if (peerData==null) {
67+
throw new CLIError("No peer data found for key: "+k);
68+
}
69+
} catch (Exception e) {
70+
throw new CLIError("Unable to access peers data",e);
71+
}
72+
73+
if (outFile==null) {
74+
outFile="peer-backup-"+k.toHexString(8)+"-"+Utils.timeString()+".cad3";
75+
}
76+
File f=FileUtils.getFile(outFile);
77+
78+
try {
79+
FileUtils.writeCAD3(f.toPath(), peerData);
80+
inform("Peer data written to: "+f);
81+
} catch (IOException e) {
82+
throw new CLIError("Unable to write peer data",e);
83+
}
84+
}
85+
86+
}
Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
package convex.cli.peer;
22

3-
import java.io.IOException;
43
import java.util.List;
54

6-
import convex.cli.CLIError;
7-
import convex.cli.ExitCodes;
85
import convex.core.data.AccountKey;
9-
import convex.etch.EtchStore;
10-
import convex.peer.API;
116
import picocli.CommandLine.Command;
127
import picocli.CommandLine.ParentCommand;
138

@@ -25,18 +20,10 @@ public class PeerList extends APeerCommand {
2520

2621

2722
@Override
28-
public void execute() {
29-
30-
EtchStore etch=etchMixin.getEtchStore();
31-
try {
32-
List<AccountKey> keys=API.listPeers(etch);
33-
for (AccountKey k: keys) {
34-
println(k.toHexString());
35-
}
36-
} catch (IOException e) {
37-
throw new CLIError(ExitCodes.IOERR,"IO Error reating etch store at "+etch,e);
38-
} finally {
39-
etch.close();
23+
public void execute() {
24+
List<AccountKey> keys=etchMixin.getPeerList();
25+
for (AccountKey k: keys) {
26+
println(k.toHexString());
4027
}
4128
}
4229
}

convex-core/src/main/java/convex/core/cvm/Peer.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -229,16 +229,6 @@ public static Peer restorePeer(AStore store, AKeyPair keyPair, ACell rootKey) th
229229
Peer peer=Peer.fromData(keyPair,peerData);
230230
return peer;
231231
}
232-
233-
/**
234-
* Like {@link #getPeerData(AStore, ACell)} but uses a null root key.
235-
* @param store store from which to load Peer data
236-
* @return Peer data map
237-
* @throws IOException In case of IOException
238-
*/
239-
public static AMap<Keyword, ACell> getPeerData(AStore store) throws IOException {
240-
return getPeerData(store, null);
241-
}
242232

243233
/**
244234
* Gets Peer Data from a Store.

convex-peer/src/main/java/convex/peer/API.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,10 @@ public static List<Server> launchLocalPeers(List<AKeyPair> keyPairs, State genes
194194
/**
195195
* Gets the list of peers registered in the given Etch Store
196196
* @param store Store from which to read peers
197-
* @return null if peer list not present
197+
* @return A new ArrayList of keys, or null if peer list not present
198198
* @throws IOException in case of IO error reading peers from store
199199
*/
200-
public static List<AccountKey> listPeers(AStore store) throws IOException {
200+
public static ArrayList<AccountKey> listPeers(AStore store) throws IOException {
201201
AMap<ACell,ACell> data=store.getRootData();
202202
ArrayList<AccountKey> results=new ArrayList<>();
203203
if (data==null) return results;

0 commit comments

Comments
 (0)