Adding support for the 'get_block_header' API call

This commit is contained in:
Nelson R. Perez 2016-12-14 15:46:45 -05:00
parent e2154d8428
commit c20ae23921
12 changed files with 305 additions and 39 deletions

View file

@ -42,6 +42,20 @@ public class Asset extends GrapheneObject {
this.precision = precision; this.precision = precision;
} }
/**
* Constructor
* @param id: The graphene object id.
* @param symbol: The asset symbol.
* @param precision: The asset precision.
* @param issuer: Graphene object id of the issuer.
*/
public Asset(String id, String symbol, int precision, String issuer){
super(id);
this.symbol = symbol;
this.precision = precision;
this.issuer = issuer;
}
public String getSymbol(){ public String getSymbol(){
return this.symbol; return this.symbol;
} }
@ -50,6 +64,10 @@ public class Asset extends GrapheneObject {
return this.precision; return this.precision;
} }
public void setIssuer(String issuer){ this.issuer = issuer; }
public String getIssuer() { return this.issuer; }
/** /**
* Custom deserializer used to instantiate a simple version of the Asset class from the response of the * Custom deserializer used to instantiate a simple version of the Asset class from the response of the
* 'lookup_asset_symbols' API call. * 'lookup_asset_symbols' API call.
@ -62,7 +80,8 @@ public class Asset extends GrapheneObject {
String id = object.get(KEY_ID).getAsString(); String id = object.get(KEY_ID).getAsString();
String symbol = object.get(KEY_SYMBOL).getAsString(); String symbol = object.get(KEY_SYMBOL).getAsString();
int precision = object.get(KEY_PRECISION).getAsInt(); int precision = object.get(KEY_PRECISION).getAsInt();
return new Asset(id, symbol, precision); String issuer = object.get(KEY_ISSUER).getAsString();
return new Asset(id, symbol, precision, issuer);
} }
} }
} }

View file

@ -47,7 +47,7 @@ public class Main {
// test.testRandomNumberGeneration(); // test.testRandomNumberGeneration();
// test.testBrainKeyOperations(false); // test.testBrainKeyOperations(false);
// test.testBip39Opertion(); // test.testBip39Opertion();
// test.testAccountNamebyAddress(); test.testAccountNamebyAddress();
// test.testAccountNameById(); // test.testAccountNameById();
// test.testRelativeAccountHistory(); // test.testRelativeAccountHistory();
// test.testingInvoiceGeneration(); // test.testingInvoiceGeneration();
@ -60,6 +60,7 @@ public class Main {
// test.testLookupAccounts(); // test.testLookupAccounts();
// test.testDecodeMemo(); // test.testDecodeMemo();
// test.testGetRelativeAccountHistory(); // test.testGetRelativeAccountHistory();
test.testLookupAssetSymbols(); // test.testLookupAssetSymbols();
// test.testGetBlockHeader();
} }
} }

View file

@ -8,6 +8,7 @@ public class RPC {
public static final String CALL_LOGIN = "login"; public static final String CALL_LOGIN = "login";
public static final String CALL_NETWORK_BROADCAST = "network_broadcast"; public static final String CALL_NETWORK_BROADCAST = "network_broadcast";
public static final String CALL_HISTORY = "history"; public static final String CALL_HISTORY = "history";
public static final String CALL_DATABASE = "database";
public static final String CALL_GET_ACCOUNT_BY_NAME = "get_account_by_name"; public static final String CALL_GET_ACCOUNT_BY_NAME = "get_account_by_name";
public static final String CALL_GET_DYNAMIC_GLOBAL_PROPERTIES = "get_dynamic_global_properties"; public static final String CALL_GET_DYNAMIC_GLOBAL_PROPERTIES = "get_dynamic_global_properties";
public static final String CALL_BROADCAST_TRANSACTION = "broadcast_transaction"; public static final String CALL_BROADCAST_TRANSACTION = "broadcast_transaction";
@ -17,4 +18,5 @@ public class RPC {
public static final String CALL_GET_RELATIVE_ACCOUNT_HISTORY = "get_relative_account_history"; public static final String CALL_GET_RELATIVE_ACCOUNT_HISTORY = "get_relative_account_history";
public static final String CALL_LOOKUP_ACCOUNTS = "lookup_accounts"; public static final String CALL_LOOKUP_ACCOUNTS = "lookup_accounts";
public static final String CALL_LOOKUP_ASSET_SYMBOLS = "lookup_asset_symbols"; public static final String CALL_LOOKUP_ASSET_SYMBOLS = "lookup_asset_symbols";
public static final String CALL_GET_BLOCK_HEADER = "get_block_header";
} }

View file

@ -85,7 +85,9 @@ public class Test {
factory.setSSLContext(context); factory.setSSLContext(context);
WebSocket mWebSocket = factory.createSocket(OPENLEDGER_WITNESS_URL); WebSocket mWebSocket = factory.createSocket(OPENLEDGER_WITNESS_URL);
mWebSocket.addListener(new GetAccountNameById(accountId, null)); ArrayList<UserAccount> userAccounts = new ArrayList<UserAccount>();
userAccounts.add(new UserAccount(accountId));
mWebSocket.addListener(new GetAccountNameById(userAccounts, null));
mWebSocket.connect(); mWebSocket.connect();
} catch (IOException e) { } catch (IOException e) {
System.out.println("IOException. Msg: " + e.getMessage()); System.out.println("IOException. Msg: " + e.getMessage());
@ -513,7 +515,7 @@ public class Test {
}; };
BrainKey brainKey = new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0); BrainKey brainKey = new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0);
Address address = new Address(brainKey.getPrivateKey()); Address address = new Address(ECKey.fromPublicOnly(brainKey.getPrivateKey().getPubKey()));
try { try {
// Create a custom SSL context. // Create a custom SSL context.
SSLContext context = null; SSLContext context = null;
@ -523,7 +525,7 @@ public class Test {
// Set the custom SSL context. // Set the custom SSL context.
factory.setSSLContext(context); factory.setSSLContext(context);
WebSocket mWebSocket = factory.createSocket(OPENLEDGER_WITNESS_URL); WebSocket mWebSocket = factory.createSocket(BLOCK_PAY_DE);
mWebSocket.addListener(new GetAccountsByAddress(address, listener)); mWebSocket.addListener(new GetAccountsByAddress(address, listener));
mWebSocket.connect(); mWebSocket.connect();
} catch (IOException e) { } catch (IOException e) {
@ -536,6 +538,18 @@ public class Test {
} }
public void testAccountNameById() { public void testAccountNameById() {
WitnessResponseListener listener = new WitnessResponseListener() {
@Override
public void onSuccess(WitnessResponse response) {
System.out.println("onSuccess");
}
@Override
public void onError(BaseResponse.Error error) {
System.out.println("onError");
}
};
try { try {
// Create a custom SSL context. // Create a custom SSL context.
SSLContext context = null; SSLContext context = null;
@ -545,8 +559,10 @@ public class Test {
// Set the custom SSL context. // Set the custom SSL context.
factory.setSSLContext(context); factory.setSSLContext(context);
WebSocket mWebSocket = factory.createSocket(OPENLEDGER_WITNESS_URL); WebSocket mWebSocket = factory.createSocket(BLOCK_PAY_FR);
mWebSocket.addListener(new GetAccountNameById("1.2.138632", mListener)); ArrayList<UserAccount> userAccounts = new ArrayList<>();
userAccounts.add(new UserAccount("1.2.138632"));
mWebSocket.addListener(new GetAccountNameById(userAccounts, listener));
mWebSocket.connect(); mWebSocket.connect();
} catch (IOException e) { } catch (IOException e) {
System.out.println("IOException. Msg: " + e.getMessage()); System.out.println("IOException. Msg: " + e.getMessage());
@ -750,9 +766,9 @@ public class Test {
List<HistoricalTransfer> transactionHistory = (List<HistoricalTransfer>) response.result; List<HistoricalTransfer> transactionHistory = (List<HistoricalTransfer>) response.result;
System.out.println("Number of transactions: "+transactionHistory.size()); System.out.println("Number of transactions: "+transactionHistory.size());
for(HistoricalTransfer historical : transactionHistory){ for(HistoricalTransfer historical : transactionHistory){
if(historical.op != null){ if(historical.getOperation() != null){
TransferOperation op = historical.op; TransferOperation op = historical.getOperation();
System.out.println("from: "+op.getFrom().getObjectId()+", to: "+op.getTo().getObjectId()+", amount: "+op.getAssetAmount().getAmount()+", block #: "+historical.block_num); System.out.println("from: "+op.getFrom().getObjectId()+", to: "+op.getTo().getObjectId()+", amount: "+op.getAssetAmount().getAmount()+", block #: "+historical.getBlockNum());
} }
} }
} }
@ -792,7 +808,7 @@ public class Test {
System.out.println("onSuccess"); System.out.println("onSuccess");
WitnessResponse<List<Asset>> resp = response; WitnessResponse<List<Asset>> resp = response;
for(Asset asset : resp.result){ for(Asset asset : resp.result){
System.out.println("Asset: "+asset.getObjectId()+", Symbol: "+asset.getSymbol()); System.out.println("Asset: "+asset.getObjectId()+", Symbol: "+asset.getSymbol()+", supply: ");
} }
} }
@ -827,4 +843,40 @@ public class Test {
System.out.println("IOException. Msg: " + e.getMessage()); System.out.println("IOException. Msg: " + e.getMessage());
} }
} }
public void testGetBlockHeader(){
WitnessResponseListener listener = new WitnessResponseListener() {
@Override
public void onSuccess(WitnessResponse response) {
System.out.println("onSuccess");
}
@Override
public void onError(BaseResponse.Error error) {
System.out.println("onError");
}
};
SSLContext context = null;
try {
context = NaiveSSLContext.getInstance("TLS");
WebSocketFactory factory = new WebSocketFactory();
// Set the custom SSL context.
factory.setSSLContext(context);
WebSocket mWebSocket = factory.createSocket(BLOCK_PAY_DE);
mWebSocket.addListener(new GetBlockHeader(11989481, listener));
mWebSocket.connect();
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException. Msg: " + e.getMessage());
} catch (WebSocketException e) {
System.out.println("WebSocketException. Msg: " + e.getMessage());
} catch (IOException e) {
System.out.println("IOException. Msg: " + e.getMessage());
}
}
} }

View file

@ -157,12 +157,12 @@ public class TransferOperation extends BaseOperation {
JsonObject jsonObject = json.getAsJsonObject(); JsonObject jsonObject = json.getAsJsonObject();
// Deserializing AssetAmount objects // Deserializing AssetAmount objects
AssetAmount amount = context.deserialize(jsonObject.get("amount"), AssetAmount.class); AssetAmount amount = context.deserialize(jsonObject.get(KEY_AMOUNT), AssetAmount.class);
AssetAmount fee = context.deserialize(jsonObject.get("fee"), AssetAmount.class); AssetAmount fee = context.deserialize(jsonObject.get(KEY_FEE), AssetAmount.class);
// Deserializing UserAccount objects // Deserializing UserAccount objects
UserAccount from = new UserAccount(jsonObject.get("from").getAsString()); UserAccount from = new UserAccount(jsonObject.get(KEY_FROM).getAsString());
UserAccount to = new UserAccount(jsonObject.get("to").getAsString()); UserAccount to = new UserAccount(jsonObject.get(KEY_TO).getAsString());
TransferOperation transfer = new TransferOperation(from, to, amount, fee); TransferOperation transfer = new TransferOperation(from, to, amount, fee);
return transfer; return transfer;
} }

View file

@ -247,4 +247,28 @@ public class Util {
} }
return result.toString(); return result.toString();
} }
/**
* Converts a base value to an adjusted one considering the precision of the asset.
* @param assetAmount: The asset amount instance.
* @return: Converts the base
*/
public static float fromBase(AssetAmount assetAmount){
long value = assetAmount.getAmount().longValue();
int precision = assetAmount.getAsset().getPrecision();
if(precision != 0)
return value / precision;
else
return 0;
}
/**
* Converts a value and its corresponding precision to a base value.
* @param value
* @param precision
* @return
*/
public static long toBase(long value, int precision){
return (long) (value * Math.pow(10, precision));
}
} }

View file

@ -7,6 +7,7 @@ import com.google.gson.reflect.TypeToken;
import de.bitsharesmunich.graphenej.AccountOptions; import de.bitsharesmunich.graphenej.AccountOptions;
import de.bitsharesmunich.graphenej.Authority; import de.bitsharesmunich.graphenej.Authority;
import de.bitsharesmunich.graphenej.RPC; import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.UserAccount;
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable; import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener; import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.AccountProperties; import de.bitsharesmunich.graphenej.models.AccountProperties;
@ -30,11 +31,17 @@ import java.util.Map;
*/ */
public class GetAccountNameById extends WebSocketAdapter { public class GetAccountNameById extends WebSocketAdapter {
private String accountID; private String accountId;
private List<UserAccount> userAccounts;
private WitnessResponseListener mListener; private WitnessResponseListener mListener;
public GetAccountNameById(String accountID, WitnessResponseListener listener) { public GetAccountNameById(String accountId, WitnessResponseListener listener){
this.accountID = accountID; this.accountId = accountId;
this.mListener = listener;
}
public GetAccountNameById(List<UserAccount> accounts, WitnessResponseListener listener){
this.userAccounts = accounts;
this.mListener = listener; this.mListener = listener;
} }
@ -42,17 +49,13 @@ public class GetAccountNameById extends WebSocketAdapter {
public void onConnected(WebSocket websocket, Map<String, List<String>> headers) throws Exception { public void onConnected(WebSocket websocket, Map<String, List<String>> headers) throws Exception {
ArrayList<Serializable> accountParams = new ArrayList(); ArrayList<Serializable> accountParams = new ArrayList();
ArrayList<Serializable> paramAddress = new ArrayList(); ArrayList<Serializable> paramAddress = new ArrayList();
paramAddress.add(new JsonSerializable() { if(accountId == null){
@Override for(UserAccount account : userAccounts) {
public String toJsonString() { paramAddress.add(account.getObjectId());
return accountID;
} }
}else{
@Override paramAddress.add(accountId);
public JsonElement toJsonObject() {
return new JsonParser().parse(accountID);
} }
});
accountParams.add(paramAddress); accountParams.add(paramAddress);
ApiCall getAccountByAddress = new ApiCall(0, RPC.CALL_GET_ACCOUNTS, accountParams, RPC.VERSION, 1); ApiCall getAccountByAddress = new ApiCall(0, RPC.CALL_GET_ACCOUNTS, accountParams, RPC.VERSION, 1);
websocket.sendText(getAccountByAddress.toJsonString()); websocket.sendText(getAccountByAddress.toJsonString());
@ -92,7 +95,7 @@ public class GetAccountNameById extends WebSocketAdapter {
@Override @Override
public void handleCallbackError(WebSocket websocket, Throwable cause) throws Exception { public void handleCallbackError(WebSocket websocket, Throwable cause) throws Exception {
System.out.println("handleCallbackError"); System.out.println("handleCallbackError. Msg: "+cause.getMessage());
StackTraceElement[] stack = cause.getStackTrace(); StackTraceElement[] stack = cause.getStackTrace();
for(StackTraceElement element : stack) { for(StackTraceElement element : stack) {
System.out.println("> "+element.getClassName()+"."+element.getMethodName()+" : "+element.getLineNumber()); System.out.println("> "+element.getClassName()+"."+element.getMethodName()+" : "+element.getLineNumber());

View file

@ -62,7 +62,7 @@ public class GetAccountsByAddress extends WebSocketAdapter {
Gson gson = new Gson(); Gson gson = new Gson();
Type GetAccountByAddressResponse = new TypeToken<WitnessResponse<List<List<String>>>>(){}.getType(); Type GetAccountByAddressResponse = new TypeToken<WitnessResponse<List<List<String>>>>(){}.getType();
WitnessResponse<WitnessResponse<List<List<String>>>> witnessResponse = gson.fromJson(response, GetAccountByAddressResponse); WitnessResponse<List<List<String>>> witnessResponse = gson.fromJson(response, GetAccountByAddressResponse);
if (witnessResponse.error != null) { if (witnessResponse.error != null) {
this.mListener.onError(witnessResponse.error); this.mListener.onError(witnessResponse.error);
} else { } else {

View file

@ -0,0 +1,103 @@
package de.bitsharesmunich.graphenej.api;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketAdapter;
import com.neovisionaries.ws.client.WebSocketException;
import com.neovisionaries.ws.client.WebSocketFrame;
import com.sun.tools.internal.ws.processor.model.Block;
import de.bitsharesmunich.graphenej.RPC;
import de.bitsharesmunich.graphenej.interfaces.WitnessResponseListener;
import de.bitsharesmunich.graphenej.models.*;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by nelson on 12/13/16.
*/
public class GetBlockHeader extends WebSocketAdapter {
// Sequence of message ids
private final static int LOGIN_ID = 1;
private final static int GET_DATABASE_ID = 2;
private final static int GET_BLOCK_HEADER_ID = 3;
private long blockNumber;
private WitnessResponseListener mListener;
private int currentId = LOGIN_ID;
private int apiId = -1;
public GetBlockHeader(long blockNumber, WitnessResponseListener listener){
this.blockNumber = blockNumber;
this.mListener = listener;
}
@Override
public void onConnected(WebSocket websocket, Map<String, List<String>> headers) throws Exception {
ArrayList<Serializable> loginParams = new ArrayList<>();
loginParams.add(null);
loginParams.add(null);
ApiCall loginCall = new ApiCall(1, RPC.CALL_LOGIN, loginParams, RPC.VERSION, currentId);
websocket.sendText(loginCall.toJsonString());
}
@Override
public void onTextFrame(WebSocket websocket, WebSocketFrame frame) throws Exception {
String response = frame.getPayloadText();
System.out.println("<<< "+response);
Gson gson = new Gson();
BaseResponse baseResponse = gson.fromJson(response, BaseResponse.class);
if(baseResponse.error != null){
mListener.onError(baseResponse.error);
websocket.disconnect();
}else {
currentId++;
ArrayList<Serializable> emptyParams = new ArrayList<>();
if(baseResponse.id == LOGIN_ID){
ApiCall getDatabaseId = new ApiCall(1, RPC.CALL_DATABASE, emptyParams, RPC.VERSION, currentId);
websocket.sendText(getDatabaseId.toJsonString());
}else if(baseResponse.id == GET_DATABASE_ID){
Type ApiIdResponse = new TypeToken<WitnessResponse<Integer>>() {}.getType();
WitnessResponse<Integer> witnessResponse = gson.fromJson(response, ApiIdResponse);
apiId = witnessResponse.result.intValue();
ArrayList<Serializable> params = new ArrayList<>();
String blockNum = String.format("%d", this.blockNumber);
params.add(blockNum);
ApiCall loginCall = new ApiCall(apiId, RPC.CALL_GET_BLOCK_HEADER, params, RPC.VERSION, currentId);
websocket.sendText(loginCall.toJsonString());
}else if(baseResponse.id == GET_BLOCK_HEADER_ID){
Type RelativeAccountHistoryResponse = new TypeToken<WitnessResponse<BlockHeader>>(){}.getType();
WitnessResponse<BlockHeader> transfersResponse = gson.fromJson(response, RelativeAccountHistoryResponse);
mListener.onSuccess(transfersResponse);
websocket.disconnect();
}
}
}
@Override
public void onFrameSent(WebSocket websocket, WebSocketFrame frame) throws Exception {
if(frame.isTextFrame())
System.out.println(">>> "+frame.getPayloadText());
}
@Override
public void onError(WebSocket websocket, WebSocketException cause) throws Exception {
System.out.println("onError. Msg: "+cause.getMessage());
websocket.disconnect();
}
@Override
public void handleCallbackError(WebSocket websocket, Throwable cause) throws Exception {
System.out.println("handleCallbackError. Msg: "+cause.getMessage());
websocket.disconnect();
}
}

View file

@ -137,10 +137,12 @@ public class GetRelativeAccountHistory extends WebSocketAdapter {
@Override @Override
public void onError(WebSocket websocket, WebSocketException cause) throws Exception { public void onError(WebSocket websocket, WebSocketException cause) throws Exception {
System.out.println("onError. Msg: "+cause.getMessage()); System.out.println("onError. Msg: "+cause.getMessage());
websocket.disconnect();
} }
@Override @Override
public void handleCallbackError(WebSocket websocket, Throwable cause) throws Exception { public void handleCallbackError(WebSocket websocket, Throwable cause) throws Exception {
System.out.println("handleCallbackError. Msg: "+cause.getMessage()); System.out.println("handleCallbackError. Msg: "+cause.getMessage());
websocket.disconnect();
} }
} }

View file

@ -0,0 +1,12 @@
package de.bitsharesmunich.graphenej.models;
/**
* Created by nelson on 12/13/16.
*/
public class BlockHeader {
public String previous;
public String timestamp;
public String witness;
public String transaction_merkle_root;
public Object[] extension;
}

View file

@ -11,11 +11,59 @@ import de.bitsharesmunich.graphenej.TransferOperation;
* those will be filtered out of the parsed result. * those will be filtered out of the parsed result.
*/ */
public class HistoricalTransfer { public class HistoricalTransfer {
public String id; private String id;
public TransferOperation op; private TransferOperation op;
public Object[] result; public Object[] result;
public long block_num; private long block_num;
public long trx_in_block; private long trx_in_block;
public long op_in_trx; private long op_in_trx;
public long virtual_op; private long virtual_op;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public TransferOperation getOperation() {
return op;
}
public void setOperation(TransferOperation op) {
this.op = op;
}
public long getBlockNum() {
return block_num;
}
public void setBlockNum(long block_num) {
this.block_num = block_num;
}
public long getTransactionsInBlock() {
return trx_in_block;
}
public void setTransactionsInBlock(long trx_in_block) {
this.trx_in_block = trx_in_block;
}
public long getOperationsInTrx() {
return op_in_trx;
}
public void setOperationsInTrx(long op_in_trx) {
this.op_in_trx = op_in_trx;
}
public long getVirtualOp() {
return virtual_op;
}
public void setVirtualOp(long virtual_op) {
this.virtual_op = virtual_op;
}
} }