Skip to content

Commit 50c8fd0

Browse files
authored
Merge pull request #87 from Peergos/feat/new-api-calls
Add new API calls for getting ipns records, and bulk block deletion
2 parents e7452b8 + 0834816 commit 50c8fd0

File tree

3 files changed

+72
-3
lines changed

3 files changed

+72
-3
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.github.peergos</groupId>
88
<artifactId>nabu</artifactId>
9-
<version>v0.7.4</version>
9+
<version>v0.7.5</version>
1010

1111
<properties>
1212
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

src/main/java/org/peergos/AggregatedMetrics.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ private static Counter build(String name, String help) {
2323
public static final Counter API_BLOCK_GET = build("api_block_get", "Total calls to block/get.");
2424
public static final Counter API_BLOCK_PUT = build("api_block_put", "Total calls to block/put.");
2525
public static final Counter API_BLOCK_RM = build("api_block_rm", "Total calls to block/rm.");
26+
public static final Counter API_BLOCK_RM_BULK = build("api_block_rm_bulk", "Total calls to block/rm/bulk.");
2627
public static final Counter API_BLOCK_STAT = build("api_block_stat", "Total calls to block/stat.");
2728
public static final Counter API_REFS_LOCAL = build("api_refs_local", "Total calls to refs/local.");
2829
public static final Counter API_BLOCK_HAS = build("api_block_has", "Total calls to block/has.");
2930
public static final Counter API_BLOOM_ADD = build("api_bloom_add", "Total calls to bloom/add.");
3031
public static final Counter API_FIND_PROVS = build("api_dht_findprovs", "Total calls to dht/findprovs.");
32+
public static final Counter API_IPNS_GET = build("api_ipns_get", "Total calls to ipns/get.");
3133

3234
public static void startExporter(String address, int port) throws IOException {
3335
LOG.info("Starting metrics server at " + address + ":" + port);

src/main/java/org/peergos/net/APIHandler.java

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
package org.peergos.net;
22

33
import io.ipfs.cid.Cid;
4+
import io.ipfs.multihash.*;
45
import io.libp2p.core.PeerId;
6+
import io.libp2p.crypto.keys.*;
57
import org.peergos.*;
8+
import org.peergos.protocol.ipns.*;
9+
import org.peergos.protocol.ipns.pb.*;
610
import org.peergos.util.*;
711
import com.sun.net.httpserver.HttpExchange;
812

9-
import java.io.IOException;
13+
import java.io.*;
14+
import java.nio.*;
1015
import java.util.*;
1116
import java.util.logging.Logger;
1217
import java.util.stream.*;
1318

1419
public class APIHandler extends Handler {
1520
public static final String API_URL = "/api/v0/";
16-
public static final Version CURRENT_VERSION = Version.parse("0.7.2");
21+
public static final Version CURRENT_VERSION = Version.parse("0.7.5");
1722
private static final Logger LOG = Logging.LOG();
1823

1924
private static final boolean LOGGING = true;
@@ -23,12 +28,14 @@ public class APIHandler extends Handler {
2328
public static final String GET = "block/get";
2429
public static final String PUT = "block/put";
2530
public static final String RM = "block/rm";
31+
public static final String RM_BULK = "block/rm/bulk";
2632
public static final String STAT = "block/stat";
2733
public static final String REFS_LOCAL = "refs/local";
2834
public static final String BLOOM_ADD = "bloom/add";
2935
public static final String HAS = "block/has";
3036

3137
public static final String FIND_PROVS = "dht/findprovs";
38+
public static final String IPNS_GET = "ipns/get";
3239

3340
private final EmbeddedIpfs ipfs;
3441
private final int maxBlockSize;
@@ -141,6 +148,31 @@ public void handleCallToAPI(HttpExchange httpExchange) {
141148
}
142149
break;
143150
}
151+
case RM_BULK: {
152+
AggregatedMetrics.API_BLOCK_RM_BULK.inc();
153+
Map<String, Object> json = (Map<String, Object>) JSONParser.parse(new String(readFully(httpExchange.getRequestBody())));
154+
List<Cid> cids = ((List<String>)json.get("cids"))
155+
.stream()
156+
.map(Cid::decode)
157+
.collect(Collectors.toList());
158+
boolean deleted = true;
159+
for (Cid cid : cids) {
160+
deleted &= ipfs.blockstore.rm(cid).join();
161+
}
162+
163+
if (deleted) {
164+
Map res = new HashMap<>();
165+
res.put("Res", "true");
166+
replyJson(httpExchange, JSONParser.toString(res));
167+
} else {
168+
try {
169+
httpExchange.sendResponseHeaders(400, 0);
170+
} catch (IOException ioe) {
171+
HttpUtil.replyError(httpExchange, ioe);
172+
}
173+
}
174+
break;
175+
}
144176
case STAT: { // https://docs.ipfs.tech/reference/kubo/rpc/#api-v0-block-stat
145177
AggregatedMetrics.API_BLOCK_STAT.inc();
146178
if (args == null || args.size() != 1) {
@@ -217,6 +249,31 @@ public void handleCallToAPI(HttpExchange httpExchange) {
217249
replyBytes(httpExchange, sb.toString().getBytes());
218250
break;
219251
}
252+
case IPNS_GET: {
253+
AggregatedMetrics.API_IPNS_GET.inc();
254+
if (args == null || args.size() != 1) {
255+
throw new APIException("argument \"signer\" is required");
256+
}
257+
Multihash signer = Multihash.fromBase58(args.get(0));
258+
if (signer.getType() != Multihash.Type.id)
259+
throw new IllegalStateException("Can only resolve Ed25519 ipns mappings");
260+
byte[] pubKeymaterial = Arrays.copyOfRange(signer.getHash(), 4, 36);
261+
io.libp2p.core.crypto.PubKey pub = new Ed25519PublicKey(new org.bouncycastle.crypto.params.Ed25519PublicKeyParameters(pubKeymaterial, 0));
262+
List<IpnsRecord> records = ipfs.resolveRecords(pub, 1)
263+
.stream()
264+
.sorted()
265+
.collect(Collectors.toList());
266+
if (records.isEmpty())
267+
throw new IllegalStateException("Couldn't resolve " + signer);
268+
IpnsRecord latest = records.get(records.size() - 1);
269+
Ipns.IpnsEntry entry = Ipns.IpnsEntry.parseFrom(ByteBuffer.wrap(latest.raw));
270+
Map<String, Object> res = new HashMap<>();
271+
res.put("sig", ArrayOps.bytesToHex(entry.getSignatureV2().toByteArray()));
272+
res.put("data", ArrayOps.bytesToHex(entry.getData().toByteArray()));
273+
String json = JSONParser.toString(res);
274+
replyJson(httpExchange, json);
275+
break;
276+
}
220277
default: {
221278
httpExchange.sendResponseHeaders(404, 0);
222279
break;
@@ -231,4 +288,14 @@ public void handleCallToAPI(HttpExchange httpExchange) {
231288
LOG.info("API Handler handled " + path + " query in: " + (t2 - t1) + " mS");
232289
}
233290
}
291+
292+
private byte[] readFully(InputStream in) throws IOException {
293+
ByteArrayOutputStream bout = new ByteArrayOutputStream();
294+
byte[] b = new byte[0x1000];
295+
int nRead;
296+
while ((nRead = in.read(b, 0, b.length)) != -1 )
297+
bout.write(b, 0, nRead);
298+
in.close();
299+
return bout.toByteArray();
300+
}
234301
}

0 commit comments

Comments
 (0)