Skip to content

Commit

Permalink
add PriceProver and integration test
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryuya1995 committed Mar 6, 2022
1 parent 38feeb7 commit 7f75fd5
Show file tree
Hide file tree
Showing 17 changed files with 411 additions and 301 deletions.
6 changes: 3 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "depends/pagesigner-cli"]
path = depends/pagesigner-cli
url = [email protected]:AbstrLabs/pagesigner-cli.git
[submodule "depends/pagesigner-cli"]
path = depends/pagesigner-cli
url = [email protected]:AbstrLabs/pagesigner-cli.git
3 changes: 0 additions & 3 deletions .gitsubmodule

This file was deleted.

42 changes: 24 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,34 @@ create a transaction payload: call price contract’s submit_price method, with
### Usage
This CLI is built on [picocli](https://www.picocli.info).

(Optional) define an alias:

#### trigger pagersigner-cli
```alias priceprover='java -cp priceprover-0.0.2.jar com.abstrlabs.priceprover.PriceProver```

This step will normalize the asset name to the ones supported by our selected API: Alphadvantage. E.g. aIBM → IBM
Generate a headers.txt that contains HTTP request to stock price API
Invoke pagersigner-cli and output the notary file.

CLI usage (for now, will be improved soon):
```
java -cp priceprover-0.0.1.jar com.abstrlabs.priceprover.PageSignerCallBack -as aIBM -op ./out
Usage: `priceprover [-hVv] [-fi] [-as=<asset>] [-op=<outputPath>] [COMMAND]`
```
This is quite verbose. You can define an alias. For example:
given the stock symbol, notarize the price and generate the proof
```alias pagesigner='java -cp priceprover-0.0.1.jar com.abstrlabs.priceprover.PageSignerCallBack```
-as, --asset the asset name used to obtain the price data.
#### notary json parser
This step could parse the notary.json and get the required input java objects.
-fi, --firstTime if it is first time run
CLI usage :
```
java -cp priceprover-0.0.1.jar com.abstrlabs.priceprover.NotaryJsonParser -nf ./out/notary.json
-h, --help show help message and exit.
-op, --outputPath output path for generated files
-v, --verbose specify multiple -v options to increase verbosity.
for example, `-v` - info, '-vv' - debug,'-vvv' -trace
-V, --version print version information and exit.
SubCommands:
notarize Call pagesigner-cli and notarize the stock price
build Parse the notary json from pagesinger, and build the circuit/input
by xjsnark
prove Trigger libsnark and generate the proof
```

### Todo
- [ ] *update the rest steps and cli usage*
- [ ] *combine submodules together*

### Build
(Please install [maven](https://maven.apache.org/guides/getting-started/maven-in-five-minutes.html) if you haven't). To build an executable jar:
Expand All @@ -50,4 +52,8 @@ java -cp priceprover-0.0.1.jar com.abstrlabs.priceprover.NotaryJsonParser -nf ./

### Q&A

#### Cannot run program "./depends/libsnark/run_ppzksnark": error=13, Permission denied
Try
`chmod u+x ./depends/libsnark/run_ppzksnark`

### References
4 changes: 4 additions & 0 deletions depends/akosba/xjsnark/1.0/_remote.repositories
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
#Sun Mar 06 23:48:53 JST 2022
xjsnark-1.0.jar>=
xjsnark-1.0.pom>=
File renamed without changes.
9 changes: 9 additions & 0 deletions depends/akosba/xjsnark/1.0/xjsnark-1.0.pom
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>akosba</groupId>
<artifactId>xjsnark</artifactId>
<version>1.0</version>
<description>POM was created from install:install-file</description>
</project>
12 changes: 12 additions & 0 deletions depends/akosba/xjsnark/maven-metadata-local.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>akosba</groupId>
<artifactId>xjsnark</artifactId>
<versioning>
<release>1.0</release>
<versions>
<version>1.0</version>
</versions>
<lastUpdated>20220306144853</lastUpdated>
</versioning>
</metadata>
Empty file modified depends/libsnark/run_ppzksnark
100644 → 100755
Empty file.
43 changes: 0 additions & 43 deletions src/main/java/com/abstrlabs/priceprover/CLI.java

This file was deleted.

28 changes: 21 additions & 7 deletions src/main/java/com/abstrlabs/priceprover/CircuitBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,50 @@
import picocli.CommandLine.Option;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.concurrent.Callable;

@Log4j2
@Command(name = "preprocess", description = "Parse the notary json from pagesinger, do the preprocess, and build the circuit by xjsnark")
@Command(name = "build", mixinStandardHelpOptions = true, description = "Parse the notary json from pagesinger, and build the circuit/input by xjsnark")
public class CircuitBuilder implements Callable<Integer> {

public NotaryCheckInput notaryCheckInput = new NotaryCheckInput();

private final String NOTARY_PUBKEY = "-----BEGIN PUBLIC KEY-----\n" +
private static final String NOTARY_FILE_NAME = "notary.json";
private static final String NOTARY_PUBKEY = "-----BEGIN PUBLIC KEY-----\n" +
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAp3iALChsj8lOkEpY1F5BeCMcyd6\n" +
"282weDfsNf8lMYi7xEVVVq0W+is27cCnHZAc0resZHTdX4KoSrFgehhPcA==\n" +
"-----END PUBLIC KEY-----";
// recent notary pubkey (22-3-5), keep the old pubkey for test
// "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEdxg4idfkVEnjIwW8OwNtg9rG0EmajcIR3P6dmq10ZZBFxkTUCPX5BkrFT0cIFAWp2FU9Jt30pl4W4E7UEaDX+g==";

@Option(names = {"-nf", "--notaryfile"}, defaultValue = "./out/notary.json", description = "decode and preprocess notary json.")
String notaryFilePath;

@Option(names = {"-op", "--outputPath"}, defaultValue = "./out", description = "output path for generated headers and notary files")
String outputPath;

@Option(names = {"-nf", "--notaryfile"}, description = "notary file that usually named notary.json")
String notaryFilePath;

@CommandLine.Option(names = {"-fi", "--firstTime"}, description = "if it is first time run")
boolean firstTime;

@Override
public Integer call() throws Exception {
if (notaryFilePath == null) {
notaryFilePath = String.valueOf(Paths.get(outputPath, NOTARY_FILE_NAME));
}

// parse notary json
parseNotaryJson(notaryFilePath);

// build circuit
new TLSNotaryCheck(notaryCheckInput, outputPath);

if (firstTime) {
new TLSNotaryCheck(notaryCheckInput, outputPath);
} else {
// todo: only translate input
new TLSNotaryCheck(notaryCheckInput, outputPath);
}
return 0;
}

Expand Down
9 changes: 4 additions & 5 deletions src/main/java/com/abstrlabs/priceprover/LibsnarkCallBack.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import java.util.concurrent.Callable;

@Log4j2
@CommandLine.Command(name = "libsnark", description = "Trigger libsnark and generate the proof")
@CommandLine.Command(name = "prove", mixinStandardHelpOptions = true, description = "Trigger libsnark and generate the proof")
public class LibsnarkCallBack implements Callable<Integer> {

private static final String CIRCUIT_NAME = "priceProver.circuit";
Expand All @@ -21,17 +21,16 @@ public class LibsnarkCallBack implements Callable<Integer> {
private static final String GENERATE = "generate";
private static final String PROVE = "prove";

@CommandLine.Option(names = {"-op", "--outputPath"}, defaultValue = "./out", description = "output path for generated headers and notary files")
String outputPath;

@CommandLine.Option(names = {"-xc", "--xjsnarkCircuit"}, defaultValue = "./out/TLSNotaryCheck.arith", description = "the xjsnark generated circuit")
String xjsnarkCircuit;

@CommandLine.Option(names = {"-xi", "--xjsnarkInput"}, defaultValue = "./out/TLSNotaryCheck_Sample_Run1.in", description = "the xjsnark generated input")
String xjsnarkInput;

@CommandLine.Option(names = {"-op", "--outputPath"}, defaultValue = "./out", description = "output path for generated headers and notary files")
String outputPath;

@CommandLine.Option(names = {"-fi", "--firstTime"}, description = "first time run the circuit")
@CommandLine.Option(names = {"-fi", "--firstTime"}, description = "if it is first time run")
boolean firstTime;

@Override
Expand Down
153 changes: 78 additions & 75 deletions src/main/java/com/abstrlabs/priceprover/PageSignerCallBack.java
Original file line number Diff line number Diff line change
@@ -1,75 +1,78 @@
package com.abstrlabs.priceprover;

import com.abstrlabs.priceprover.util.CommandExecutor;
import lombok.extern.log4j.Log4j2;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.concurrent.Callable;

@Log4j2
@Command(name = "pagesigner", description = "Call pagesigner-cli and generate a stock price notray json")
public class PageSignerCallBack implements Callable<Integer> {

@Option(names = {"-as", "--asset"}, defaultValue = "aIBM", description = "the asset name used to obtain the price data jason and the notary file via PageSinger.")
String asset;

@Option(names = {"-op", "--outputPath"}, defaultValue = "./out", description = "output path for generated headers and notary files")
String outputPath;

@Override
public Integer call(){
String assetName = normalizeAssetName(asset);

try {
//generate header.txt
String currentWorkingDir = System.getProperty("user.dir");
String headersPath = currentWorkingDir + "/headers.txt";
String content = "GET /query?function=GLOBAL_QUOTE&symbol=" + assetName + "&apikey=demo HTTP/1.1\n" +
"Host: www.alphavantage.co";
File headersFile = new File(headersPath);
if (headersFile.createNewFile()) {
log.info("Headers file created successfully");
};
FileWriter headersWriter = new FileWriter(headersFile);
headersWriter.write(content);
headersWriter.close();

//call pagesigner-cli
String[] pagesignerCommand = new String[]{"./depends/pagesigner-cli/pgsg-node.js", "notarize", "www.alphavantage.co", "--headers", headersPath, outputPath};
CommandExecutor ce = new CommandExecutor();
String missionName = "Call pagesigner-cli";
if (ce.execute(missionName, pagesignerCommand)) {
log.info("saved the notary file into path:" + outputPath);
return 0;
} else {
return -1;
}

} catch (IOException e) {
e.printStackTrace();
return -2;
}
}

/**
* input : asset name, eg. aIBM, aAAPL
* output: normalized asset name, eg. IBM, AAPL
*/
private String normalizeAssetName(String asset) {
if (asset.length() > 1 && asset.charAt(0) == 'a') {
asset = asset.substring(1);
}
log.info("The normalized asset name is " + asset);
return asset;
}

public static void main(String[] args) {
int exitCode = new CommandLine(new PageSignerCallBack()).execute(args);
System.exit(exitCode);
}
}
package com.abstrlabs.priceprover;

import com.abstrlabs.priceprover.util.CommandExecutor;
import lombok.extern.log4j.Log4j2;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.Callable;

@Log4j2
@Command(name = "notarize", description = "Call pagesigner-cli and notarize the stock price")
public class PageSignerCallBack implements Callable<Integer> {

private static final String HEADERS = "headers";

@Option(names = {"-as", "--asset"}, defaultValue = "aIBM", description = "the asset name used to obtain the price data jason and the notary file via PageSinger.")
String asset;

@Option(names = {"-op", "--outputPath"}, defaultValue = "./out", description = "output path for generated headers and notary files")
String outputPath;

@Override
public Integer call(){
String assetName = normalizeAssetName(asset);

try {
// generate header.txt
String headersPath = String.valueOf(Paths.get(outputPath, HEADERS));
String content = "GET /query?function=GLOBAL_QUOTE&symbol=" + assetName + "&apikey=demo HTTP/1.1\n" +
"Host: www.alphavantage.co";
File headersFile = new File(headersPath);
if (headersFile.createNewFile()) {
log.info("Headers file created successfully");
};
FileWriter headersWriter = new FileWriter(headersFile);
headersWriter.write(content);
headersWriter.close();

// call pagesigner-cli
String[] pagesignerCommand = new String[]{"./depends/pagesigner-cli/pgsg-node.js", "notarize", "www.alphavantage.co", "--headers", headersPath, outputPath};
CommandExecutor ce = new CommandExecutor();
String missionName = "Call pagesigner-cli";
if (ce.execute(missionName, pagesignerCommand)) {
log.info("saved the notary file into path:" + outputPath);
return 0;
} else {
return -1;
}

} catch (IOException e) {
e.printStackTrace();
return -2;
}
}

/**
* input : asset name, eg. aIBM, aAAPL
* output: normalized asset name, eg. IBM, AAPL
*/
private String normalizeAssetName(String asset) {
if (asset.length() > 1 && asset.charAt(0) == 'a') {
asset = asset.substring(1);
}
log.debug("The normalized asset name is " + asset);
return asset;
}

public static void main(String[] args) {
int exitCode = new CommandLine(new PageSignerCallBack()).execute(args);
System.exit(exitCode);
}
}
Loading

0 comments on commit 7f75fd5

Please sign in to comment.