Adding support for account options update
This commit is contained in:
parent
7eb6a15c7e
commit
df41775f50
16 changed files with 482 additions and 123 deletions
134
src/main/java/com/luminiasoft/bitshares/AccountOptions.java
Normal file
134
src/main/java/com/luminiasoft/bitshares/AccountOptions.java
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
package com.luminiasoft.bitshares;
|
||||||
|
|
||||||
|
import com.google.common.primitives.Bytes;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.luminiasoft.bitshares.interfaces.GrapheneSerializable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by nelson on 12/5/16.
|
||||||
|
*/
|
||||||
|
public class AccountOptions implements GrapheneSerializable {
|
||||||
|
public static final String KEY_MEMO_KEY = "memo_key";
|
||||||
|
public static final String KEY_NUM_COMMITTEE = "num_committee";
|
||||||
|
public static final String KEY_NUM_WITNESS = "num_witness";
|
||||||
|
public static final String KEY_VOTES = "votes";
|
||||||
|
public static final String KEY_VOTING_ACCOUNT = "voting_account";
|
||||||
|
public static final String KEY_EXTENSIONS = Extensions.KEY_EXTENSIONS;
|
||||||
|
|
||||||
|
private PublicKey memo_key;
|
||||||
|
private UserAccount voting_account;
|
||||||
|
private int num_witness;
|
||||||
|
private int num_comittee;
|
||||||
|
private Vote[] votes;
|
||||||
|
private Extensions extensions;
|
||||||
|
|
||||||
|
public AccountOptions(){
|
||||||
|
voting_account = new UserAccount(UserAccount.PROXY_TO_SELF);
|
||||||
|
this.votes = new Vote[0];
|
||||||
|
this.extensions = new Extensions();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountOptions(PublicKey memoKey){
|
||||||
|
this();
|
||||||
|
this.memo_key = memoKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PublicKey getMemoKey() {
|
||||||
|
return memo_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMemoKey(PublicKey memo_key) {
|
||||||
|
this.memo_key = memo_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserAccount getVotingAccount() {
|
||||||
|
return voting_account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVotingAccount(UserAccount voting_account) {
|
||||||
|
this.voting_account = voting_account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumWitness() {
|
||||||
|
return num_witness;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumWitness(int num_witness) {
|
||||||
|
this.num_witness = num_witness;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumComittee() {
|
||||||
|
return num_comittee;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNum_comittee(int num_comittee) {
|
||||||
|
this.num_comittee = num_comittee;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vote[] getVotes() {
|
||||||
|
return votes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVotes(Vote[] votes) {
|
||||||
|
this.votes = votes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] toBytes() {
|
||||||
|
List<Byte> byteArray = new ArrayList<Byte>();
|
||||||
|
|
||||||
|
if(memo_key != null){
|
||||||
|
// Adding byte to indicate that there is memo data
|
||||||
|
byteArray.add((byte) 1);
|
||||||
|
|
||||||
|
// Adding memo key
|
||||||
|
byteArray.addAll(Bytes.asList(memo_key.toBytes()));
|
||||||
|
|
||||||
|
// Adding voting account
|
||||||
|
byteArray.addAll(Bytes.asList(voting_account.toBytes()));
|
||||||
|
|
||||||
|
// Adding num_witness
|
||||||
|
byteArray.addAll(Bytes.asList(Util.revertShort(Short.valueOf((short) num_witness))));
|
||||||
|
|
||||||
|
// Adding num_committee
|
||||||
|
byteArray.addAll(Bytes.asList(Util.revertShort(Short.valueOf((short) num_comittee))));
|
||||||
|
|
||||||
|
// Vote's array length
|
||||||
|
byteArray.add((byte) votes.length);
|
||||||
|
|
||||||
|
for(Vote vote : votes){
|
||||||
|
//TODO: Check this serialization
|
||||||
|
byteArray.addAll(Bytes.asList(vote.toBytes()));
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
byteArray.add((byte) 0);
|
||||||
|
}
|
||||||
|
return Bytes.toArray(byteArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toJsonString() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement toJsonObject() {
|
||||||
|
JsonObject options = new JsonObject();
|
||||||
|
options.addProperty(KEY_MEMO_KEY, new Address(memo_key.getKey()).toString());
|
||||||
|
options.addProperty(KEY_NUM_COMMITTEE, num_comittee);
|
||||||
|
options.addProperty(KEY_NUM_WITNESS, num_witness);
|
||||||
|
options.addProperty(KEY_VOTING_ACCOUNT, voting_account.getObjectId());
|
||||||
|
JsonArray votesArray = new JsonArray();
|
||||||
|
for(Vote vote : votes){
|
||||||
|
//TODO: Add votes representation
|
||||||
|
}
|
||||||
|
options.add(KEY_VOTES, votesArray);
|
||||||
|
options.add(KEY_EXTENSIONS, extensions.toJsonObject());
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,8 @@ import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import com.sun.istack.internal.NotNull;
|
||||||
|
import com.sun.istack.internal.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to encapsulate operations related to the account_update_operation.
|
* Class used to encapsulate operations related to the account_update_operation.
|
||||||
|
@ -15,25 +17,36 @@ public class AccountUpdateOperation extends BaseOperation {
|
||||||
public static final String KEY_OWNER = "owner";
|
public static final String KEY_OWNER = "owner";
|
||||||
public static final String KEY_ACTIVE = "active";
|
public static final String KEY_ACTIVE = "active";
|
||||||
public static final String KEY_FEE = "fee";
|
public static final String KEY_FEE = "fee";
|
||||||
|
public static final String KEY_NEW_OPTIONS = "new_options";
|
||||||
public static final String KEY_EXTENSIONS = "extensions";
|
public static final String KEY_EXTENSIONS = "extensions";
|
||||||
|
|
||||||
private UserAccount account;
|
|
||||||
private AssetAmount fee;
|
private AssetAmount fee;
|
||||||
private Authority owner;
|
private UserAccount account;
|
||||||
private Authority active;
|
private Optional<Authority> owner;
|
||||||
|
private Optional<Authority> active;
|
||||||
|
private Optional<AccountOptions> new_options;
|
||||||
private Extensions extensions;
|
private Extensions extensions;
|
||||||
|
|
||||||
public AccountUpdateOperation(UserAccount account, Authority owner, Authority active, AssetAmount fee){
|
/**
|
||||||
|
* Account update operation constructor.
|
||||||
|
* @param account User account to update. Can't be null.
|
||||||
|
* @param owner Owner authority to set. Can be null.
|
||||||
|
* @param active Active authority to set. Can be null.
|
||||||
|
* @param options Active authority to set. Can be null.
|
||||||
|
* @param fee The fee to pay. Can be null.
|
||||||
|
*/
|
||||||
|
public AccountUpdateOperation(UserAccount account, Authority owner, Authority active, AccountOptions options, AssetAmount fee){
|
||||||
super(OperationType.account_update_operation);
|
super(OperationType.account_update_operation);
|
||||||
this.account = account;
|
|
||||||
this.owner = owner;
|
|
||||||
this.active = active;
|
|
||||||
this.fee = fee;
|
this.fee = fee;
|
||||||
|
this.account = account;
|
||||||
|
this.owner = new Optional<>(owner);
|
||||||
|
this.active = new Optional<>(active);
|
||||||
|
this.new_options = new Optional<>(options);
|
||||||
extensions = new Extensions();
|
extensions = new Extensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccountUpdateOperation(UserAccount account, Authority owner, Authority active){
|
public AccountUpdateOperation(UserAccount account, Authority owner, Authority active, AccountOptions options){
|
||||||
this(account, owner, active, new AssetAmount(UnsignedLong.valueOf(0), new Asset("1.3.0")));
|
this(account, owner, active, options, new AssetAmount(UnsignedLong.valueOf(0), new Asset("1.3.0")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -41,6 +54,18 @@ public class AccountUpdateOperation extends BaseOperation {
|
||||||
this.fee = fee;
|
this.fee = fee;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOwner(Authority owner){
|
||||||
|
this.owner = new Optional<>(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActive(Authority active){
|
||||||
|
this.active = new Optional<>(active);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountOptions(AccountOptions options){
|
||||||
|
this.new_options = new Optional<>(options);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toJsonString() {
|
public String toJsonString() {
|
||||||
Gson gson = new Gson();
|
Gson gson = new Gson();
|
||||||
|
@ -57,6 +82,7 @@ public class AccountUpdateOperation extends BaseOperation {
|
||||||
accountUpdate.addProperty(KEY_ACCOUNT, account.toJsonString());
|
accountUpdate.addProperty(KEY_ACCOUNT, account.toJsonString());
|
||||||
accountUpdate.add(KEY_OWNER, owner.toJsonObject());
|
accountUpdate.add(KEY_OWNER, owner.toJsonObject());
|
||||||
accountUpdate.add(KEY_ACTIVE, active.toJsonObject());
|
accountUpdate.add(KEY_ACTIVE, active.toJsonObject());
|
||||||
|
accountUpdate.add(KEY_NEW_OPTIONS, new_options.toJsonObject());
|
||||||
accountUpdate.add(KEY_EXTENSIONS, extensions.toJsonObject());
|
accountUpdate.add(KEY_EXTENSIONS, extensions.toJsonObject());
|
||||||
array.add(accountUpdate);
|
array.add(accountUpdate);
|
||||||
return array;
|
return array;
|
||||||
|
@ -68,7 +94,8 @@ public class AccountUpdateOperation extends BaseOperation {
|
||||||
byte[] accountBytes = account.toBytes();
|
byte[] accountBytes = account.toBytes();
|
||||||
byte[] ownerBytes = owner.toBytes();
|
byte[] ownerBytes = owner.toBytes();
|
||||||
byte[] activeBytes = active.toBytes();
|
byte[] activeBytes = active.toBytes();
|
||||||
|
byte[] newOptionsBytes = new_options.toBytes();
|
||||||
byte[] extensionBytes = extensions.toBytes();
|
byte[] extensionBytes = extensions.toBytes();
|
||||||
return Bytes.concat(feeBytes, accountBytes, ownerBytes, activeBytes, extensionBytes);
|
return Bytes.concat(feeBytes, accountBytes, ownerBytes, activeBytes, newOptionsBytes, extensionBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,66 @@
|
||||||
package com.luminiasoft.bitshares;
|
package com.luminiasoft.bitshares;
|
||||||
|
|
||||||
|
import com.luminiasoft.bitshares.errors.MalformedTransactionException;
|
||||||
|
import org.bitcoinj.core.ECKey;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by nelson on 12/3/16.
|
* Class used to build a transaction containing an account update operation.
|
||||||
*/
|
*/
|
||||||
public class AccountUpdateTransactionBuilder {
|
public class AccountUpdateTransactionBuilder extends TransactionBuilder {
|
||||||
private List<AccountUpdateOperation> operations;
|
private List<BaseOperation> operations;
|
||||||
|
private AssetAmount fee;
|
||||||
|
private UserAccount account;
|
||||||
|
private Authority owner;
|
||||||
|
private Authority active;
|
||||||
|
private AccountOptions new_options;
|
||||||
|
|
||||||
|
public AccountUpdateTransactionBuilder(ECKey privKey) {
|
||||||
|
super(privKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public AccountUpdateTransactionBuilder setAccont(UserAccount account){
|
||||||
|
this.account = account;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountUpdateTransactionBuilder setOwner(Authority owner){
|
||||||
|
this.owner = owner;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountUpdateTransactionBuilder setActive(Authority active){
|
||||||
|
this.active = active;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountUpdateTransactionBuilder setOptions(AccountOptions options){
|
||||||
|
this.new_options = options;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountUpdateTransactionBuilder setFee(AssetAmount fee){
|
||||||
|
this.fee = fee;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Transaction build() throws MalformedTransactionException {
|
||||||
|
if(account == null){
|
||||||
|
throw new MalformedTransactionException("Missing required account information");
|
||||||
|
}else{
|
||||||
|
operations = new ArrayList<>();
|
||||||
|
AccountUpdateOperation operation;
|
||||||
|
if(fee == null){
|
||||||
|
operation = new AccountUpdateOperation(account, owner, active, new_options);
|
||||||
|
}else{
|
||||||
|
operation = new AccountUpdateOperation(account, owner, active, new_options, fee);
|
||||||
|
}
|
||||||
|
operations.add(operation);
|
||||||
|
}
|
||||||
|
return new Transaction(privateKey, blockData, operations);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,14 @@ import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.luminiasoft.bitshares.errors.MalformedAddressException;
|
import com.luminiasoft.bitshares.errors.MalformedAddressException;
|
||||||
import com.luminiasoft.bitshares.interfaces.ByteSerializable;
|
import com.luminiasoft.bitshares.interfaces.GrapheneSerializable;
|
||||||
import com.luminiasoft.bitshares.interfaces.JsonSerializable;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by nelson on 11/30/16.
|
* Created by nelson on 11/30/16.
|
||||||
*/
|
*/
|
||||||
public class Authority implements JsonSerializable, ByteSerializable {
|
public class Authority implements GrapheneSerializable {
|
||||||
public static final String KEY_ACCOUNT_AUTHS = "account_auths";
|
public static final String KEY_ACCOUNT_AUTHS = "account_auths";
|
||||||
public static final String KEY_KEY_AUTHS = "key_auths";
|
public static final String KEY_KEY_AUTHS = "key_auths";
|
||||||
public static final String KEY_WEIGHT_THRESHOLD = "weight_threshold";
|
public static final String KEY_WEIGHT_THRESHOLD = "weight_threshold";
|
||||||
|
@ -25,17 +23,41 @@ public class Authority implements JsonSerializable, ByteSerializable {
|
||||||
private HashMap<PublicKey, Integer> key_auths;
|
private HashMap<PublicKey, Integer> key_auths;
|
||||||
private Extensions extensions;
|
private Extensions extensions;
|
||||||
|
|
||||||
public Authority(long weight_threshold, HashMap<String, Integer> keyAuths) throws MalformedAddressException {
|
public Authority(){
|
||||||
this.weight_threshold = weight_threshold;
|
this.weight_threshold = 1;
|
||||||
key_auths = new HashMap<PublicKey, Integer>();
|
this.account_auths = new HashMap<UserAccount, Integer>();
|
||||||
for(String key : keyAuths.keySet()){
|
this.key_auths = new HashMap<PublicKey, Integer>();
|
||||||
Address address = new Address(key);
|
|
||||||
key_auths.put(address.getPublicKey(), keyAuths.get(key));
|
|
||||||
}
|
|
||||||
account_auths = new HashMap<UserAccount, Integer>();
|
|
||||||
extensions = new Extensions();
|
extensions = new Extensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the authority class that takes every possible detail.
|
||||||
|
* @param weight_threshold: The total weight threshold
|
||||||
|
* @param keyAuths: Map of key to weights relationships. Can be null.
|
||||||
|
* @param accountAuths: Map of account to weights relationships. Can be null.
|
||||||
|
* @throws MalformedAddressException
|
||||||
|
*/
|
||||||
|
public Authority(long weight_threshold, HashMap<PublicKey, Integer> keyAuths, HashMap<UserAccount, Integer> accountAuths) {
|
||||||
|
this();
|
||||||
|
this.weight_threshold = weight_threshold;
|
||||||
|
if(keyAuths != null)
|
||||||
|
this.key_auths = keyAuths;
|
||||||
|
if(accountAuths != null)
|
||||||
|
this.account_auths = accountAuths;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeyAuthorities(HashMap<Address, Integer> keyAuths){
|
||||||
|
if(keyAuths != null){
|
||||||
|
for(Address address : keyAuths.keySet()){
|
||||||
|
key_auths.put(address.getPublicKey(), keyAuths.get(address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountAuthorities(HashMap<UserAccount, Integer> accountAuthorities){
|
||||||
|
this.account_auths = accountAuthorities;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toJsonString() {
|
public String toJsonString() {
|
||||||
return null;
|
return null;
|
||||||
|
@ -74,25 +96,34 @@ public class Authority implements JsonSerializable, ByteSerializable {
|
||||||
// Adding number of authorities
|
// Adding number of authorities
|
||||||
byteArray.add(Byte.valueOf((byte) (account_auths.size() + key_auths.size())));
|
byteArray.add(Byte.valueOf((byte) (account_auths.size() + key_auths.size())));
|
||||||
|
|
||||||
// Weight threshold
|
// If the authority is not empty of references, we serialize its contents
|
||||||
byteArray.addAll(Bytes.asList(Util.revertInteger(new Integer((int) weight_threshold))));
|
// otherwise its only contribution will be a zero byte
|
||||||
|
if(account_auths.size() + key_auths.size() > 0){
|
||||||
|
// Weight threshold
|
||||||
|
byteArray.addAll(Bytes.asList(Util.revertInteger(new Integer((int) weight_threshold))));
|
||||||
|
|
||||||
// Number of account authorities
|
// Number of account authorities
|
||||||
byteArray.add((byte) account_auths.size());
|
byteArray.add((byte) account_auths.size());
|
||||||
|
|
||||||
//TODO: Add account authorities
|
//TODO: Check the account authorities serialization
|
||||||
|
// Serializing individual accounts and their corresponding weights
|
||||||
|
for(UserAccount account : account_auths.keySet()){
|
||||||
|
byteArray.addAll(Bytes.asList(account.toBytes()));
|
||||||
|
byteArray.addAll(Bytes.asList(Util.revertShort(account_auths.get(account).shortValue())));
|
||||||
|
}
|
||||||
|
|
||||||
// Number of key authorities
|
// Number of key authorities
|
||||||
byteArray.add((byte) key_auths.size());
|
byteArray.add((byte) key_auths.size());
|
||||||
|
|
||||||
for(PublicKey publicKey : key_auths.keySet()){
|
// Serializing individual keys and their corresponding weights
|
||||||
byteArray.addAll(Bytes.asList(publicKey.toBytes()));
|
for(PublicKey publicKey : key_auths.keySet()){
|
||||||
byteArray.addAll(Bytes.asList(Util.revertShort(key_auths.get(publicKey).shortValue())));
|
byteArray.addAll(Bytes.asList(publicKey.toBytes()));
|
||||||
|
byteArray.addAll(Bytes.asList(Util.revertShort(key_auths.get(publicKey).shortValue())));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding number of extensions
|
||||||
|
byteArray.add((byte) extensions.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adding number of extensions
|
|
||||||
byteArray.add((byte) extensions.size());
|
|
||||||
|
|
||||||
return Bytes.toArray(byteArray);
|
return Bytes.toArray(byteArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,6 +11,8 @@ import java.util.ArrayList;
|
||||||
* Created by nelson on 11/9/16.
|
* Created by nelson on 11/9/16.
|
||||||
*/
|
*/
|
||||||
public class Extensions implements JsonSerializable, ByteSerializable {
|
public class Extensions implements JsonSerializable, ByteSerializable {
|
||||||
|
public static final String KEY_EXTENSIONS = "extensions";
|
||||||
|
|
||||||
private ArrayList<JsonSerializable> extensions;
|
private ArrayList<JsonSerializable> extensions;
|
||||||
|
|
||||||
public Extensions(){
|
public Extensions(){
|
||||||
|
|
|
@ -11,6 +11,8 @@ public class Main {
|
||||||
|
|
||||||
public static final String BILTHON_5_BRAIN_KEY = "UNMATE AURIGAL NAVET WAVICLE REWOVE ABBOTCY COWHERB OUTKICK STOPPER JUSSORY BEAMLET WIRY";
|
public static final String BILTHON_5_BRAIN_KEY = "UNMATE AURIGAL NAVET WAVICLE REWOVE ABBOTCY COWHERB OUTKICK STOPPER JUSSORY BEAMLET WIRY";
|
||||||
|
|
||||||
|
public static final String BILTHON_7_BRAIN_KEY = "VENIN QUOTHA OBESELY TORIC OSMATIC SPOKEN DIACOPE CUBICA TABULA REDDING APONIA TARTAR";
|
||||||
|
|
||||||
//public static final String BRAIN_KEY = "TWIXT SERMO TRILLI AUDIO PARDED PLUMET BIWA REHUNG MAUDLE VALVULA OUTBURN FEWNESS ALIENER UNTRACE PRICH TROKER";
|
//public static final String BRAIN_KEY = "TWIXT SERMO TRILLI AUDIO PARDED PLUMET BIWA REHUNG MAUDLE VALVULA OUTBURN FEWNESS ALIENER UNTRACE PRICH TROKER";
|
||||||
//public static final String BRAIN_KEY = "SIVER TIKKER FOGO HOMINAL PRAYER LUTEIN SMALLY ACARID MEROPIA TRANCE BOGONG IDDAT HICKORY SOUTANE MOOD DOWSER";
|
//public static final String BRAIN_KEY = "SIVER TIKKER FOGO HOMINAL PRAYER LUTEIN SMALLY ACARID MEROPIA TRANCE BOGONG IDDAT HICKORY SOUTANE MOOD DOWSER";
|
||||||
public static final String BIP39_KEY = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
public static final String BIP39_KEY = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||||
|
@ -55,7 +57,7 @@ public class Main {
|
||||||
// test.testGetAccountByName();
|
// test.testGetAccountByName();
|
||||||
// test.testGetRequiredFees();
|
// test.testGetRequiredFees();
|
||||||
// test.testRandomNumberGeneration();
|
// test.testRandomNumberGeneration();
|
||||||
// test.testBrainKeyOperations(false);
|
// test.testBrainKeyOperations(true);
|
||||||
// test.testBip39Opertion();
|
// test.testBip39Opertion();
|
||||||
// test.testAccountNamebyAddress();
|
// test.testAccountNamebyAddress();
|
||||||
// test.testAccountNameById();
|
// test.testAccountNameById();
|
||||||
|
|
33
src/main/java/com/luminiasoft/bitshares/Optional.java
Normal file
33
src/main/java/com/luminiasoft/bitshares/Optional.java
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package com.luminiasoft.bitshares;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.luminiasoft.bitshares.interfaces.GrapheneSerializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used whenever we have an optional field.
|
||||||
|
*/
|
||||||
|
public class Optional<T extends GrapheneSerializable> implements GrapheneSerializable {
|
||||||
|
private T optionalField;
|
||||||
|
|
||||||
|
public Optional(T field){
|
||||||
|
optionalField = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] toBytes() {
|
||||||
|
if(optionalField == null)
|
||||||
|
return new byte[] { (byte) 0 };
|
||||||
|
else
|
||||||
|
return optionalField.toBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toJsonString() {
|
||||||
|
return optionalField.toJsonString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonElement toJsonObject() {
|
||||||
|
return optionalField.toJsonObject();
|
||||||
|
}
|
||||||
|
}
|
|
@ -341,8 +341,8 @@ public class Test {
|
||||||
.setDestination(new UserAccount("1.2.129848"))
|
.setDestination(new UserAccount("1.2.129848"))
|
||||||
.setAmount(new AssetAmount(UnsignedLong.valueOf(100), new Asset("1.3.120")))
|
.setAmount(new AssetAmount(UnsignedLong.valueOf(100), new Asset("1.3.120")))
|
||||||
.setFee(new AssetAmount(UnsignedLong.valueOf(264174), new Asset("1.3.0")))
|
.setFee(new AssetAmount(UnsignedLong.valueOf(264174), new Asset("1.3.0")))
|
||||||
.setBlockData(new BlockData(Main.REF_BLOCK_NUM, Main.REF_BLOCK_PREFIX, Main.RELATIVE_EXPIRATION))
|
|
||||||
.setPrivateKey(DumpedPrivateKey.fromBase58(null, Main.WIF).getKey())
|
.setPrivateKey(DumpedPrivateKey.fromBase58(null, Main.WIF).getKey())
|
||||||
|
.setBlockData(new BlockData(Main.REF_BLOCK_NUM, Main.REF_BLOCK_PREFIX, Main.RELATIVE_EXPIRATION))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
ArrayList<Serializable> transactionList = new ArrayList<>();
|
ArrayList<Serializable> transactionList = new ArrayList<>();
|
||||||
|
@ -532,49 +532,6 @@ public class Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRandomNumberGeneration() {
|
|
||||||
byte[] seed = new byte[]{new Long(System.nanoTime()).byteValue()};
|
|
||||||
doCountTest(new SHA512Digest(), seed);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doCountTest(Digest digest, byte[] seed)//, byte[] expectedXors)
|
|
||||||
{
|
|
||||||
DigestRandomGenerator generator = new DigestRandomGenerator(digest);
|
|
||||||
byte[] output = new byte[digest.getDigestSize()];
|
|
||||||
int[] averages = new int[digest.getDigestSize()];
|
|
||||||
byte[] ands = new byte[digest.getDigestSize()];
|
|
||||||
byte[] xors = new byte[digest.getDigestSize()];
|
|
||||||
byte[] ors = new byte[digest.getDigestSize()];
|
|
||||||
|
|
||||||
generator.addSeedMaterial(seed);
|
|
||||||
|
|
||||||
for (int i = 0; i != 1000000; i++) {
|
|
||||||
generator.nextBytes(output);
|
|
||||||
for (int j = 0; j != output.length; j++) {
|
|
||||||
averages[j] += output[j] & 0xff;
|
|
||||||
ands[j] &= output[j];
|
|
||||||
xors[j] ^= output[j];
|
|
||||||
ors[j] |= output[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i != output.length; i++) {
|
|
||||||
if ((averages[i] / 1000000) != 127) {
|
|
||||||
System.out.println("average test failed for " + digest.getAlgorithmName());
|
|
||||||
}
|
|
||||||
System.out.println("averages[" + i + "] / 1000000: " + averages[i] / 1000000);
|
|
||||||
if (ands[i] != 0) {
|
|
||||||
System.out.println("and test failed for " + digest.getAlgorithmName());
|
|
||||||
}
|
|
||||||
if ((ors[i] & 0xff) != 0xff) {
|
|
||||||
System.out.println("or test failed for " + digest.getAlgorithmName());
|
|
||||||
}
|
|
||||||
// if (xors[i] != expectedXors[i]) {
|
|
||||||
// System.out.println("xor test failed for " + digest.getAlgorithmName());
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The final purpose of this test is to convert the plain brainkey at
|
* The final purpose of this test is to convert the plain brainkey at
|
||||||
* Main.BRAIN_KEY into the WIF at Main.WIF
|
* Main.BRAIN_KEY into the WIF at Main.WIF
|
||||||
|
@ -595,29 +552,21 @@ public class Test {
|
||||||
brainKey = new BrainKey(Main.BILTHON_5_BRAIN_KEY, 0);
|
brainKey = new BrainKey(Main.BILTHON_5_BRAIN_KEY, 0);
|
||||||
}
|
}
|
||||||
ECKey key = brainKey.getPrivateKey();
|
ECKey key = brainKey.getPrivateKey();
|
||||||
System.out.println("Private key");
|
System.out.println("Private key..................: "+Util.bytesToHex(key.getSecretBytes()));
|
||||||
System.out.println(Util.bytesToHex(key.getSecretBytes()));
|
|
||||||
String wif = key.getPrivateKeyAsWiF(NetworkParameters.fromID(NetworkParameters.ID_MAINNET));
|
String wif = key.getPrivateKeyAsWiF(NetworkParameters.fromID(NetworkParameters.ID_MAINNET));
|
||||||
System.out.println("wif compressed: " + wif);
|
System.out.println("Wif Compressed...............: " + wif);
|
||||||
String wif2 = key.decompress().getPrivateKeyAsWiF(NetworkParameters.fromID(NetworkParameters.ID_MAINNET));
|
String wif2 = key.decompress().getPrivateKeyAsWiF(NetworkParameters.fromID(NetworkParameters.ID_MAINNET));
|
||||||
System.out.println("wif decompressed: " + wif2);
|
System.out.println("Wif Decompressed.............: " + wif2);
|
||||||
|
|
||||||
byte[] pubKey1 = key.decompress().getPubKey();
|
byte[] pubKey1 = key.decompress().getPubKey();
|
||||||
System.out.println("decompressed public key: " + Base58.encode(pubKey1));
|
|
||||||
byte[] pubKey2 = key.getPubKey();
|
byte[] pubKey2 = key.getPubKey();
|
||||||
System.out.println("compressed public key: " + Base58.encode(pubKey2));
|
|
||||||
|
|
||||||
System.out.println("pub key compressed : " + Util.bytesToHex(pubKey1));
|
System.out.println("Public Key Decompressed........: " + Util.bytesToHex(pubKey1));
|
||||||
System.out.println("pub key uncompressed : " + Util.bytesToHex(pubKey2));
|
System.out.println("Public Key Compressed..........: " + Util.bytesToHex(pubKey2));
|
||||||
|
|
||||||
byte[] pubKey3 = key.getPubKeyPoint().getEncoded(true);
|
|
||||||
System.out.println("pub key compressed : " + Base58.encode(pubKey3));
|
|
||||||
|
|
||||||
// Address generation test
|
// Address generation test
|
||||||
Address address = new Address(key);
|
Address address = new Address(key);
|
||||||
System.out.println("Block explorer's address: " + address);
|
System.out.println("Block explorer's address.....: " + address);
|
||||||
|
|
||||||
System.out.println("Wif: : " + brainKey.getWalletImportFormat());
|
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
System.out.println("FileNotFoundException. Msg: " + e.getMessage());
|
System.out.println("FileNotFoundException. Msg: " + e.getMessage());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -744,20 +693,30 @@ public class Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAccountUpdateSerialization() {
|
public void testAccountUpdateSerialization() {
|
||||||
UserAccount account = new UserAccount("1.2.138632");
|
String newAddress = "BTS8RiFgs8HkcVPVobHLKEv6yL3iXcC9SWjbPVS15dDAXLG9GYhnY";
|
||||||
AssetAmount fee = new AssetAmount(UnsignedLong.valueOf("200"), new Asset("1.3.0"));
|
|
||||||
HashMap<String, Integer> keyAuths = new HashMap<>();
|
|
||||||
keyAuths.put("BTS8RiFgs8HkcVPVobHLKEv6yL3iXcC9SWjbPVS15dDAXLG9GYhnY", 1);
|
|
||||||
try {
|
try {
|
||||||
BlockData blockData = new BlockData(0, 0, 0);
|
Address address = new Address(newAddress);
|
||||||
Authority owner = new Authority(1, keyAuths);
|
HashMap<PublicKey, Integer> authMap = new HashMap<>();
|
||||||
Authority active = new Authority(1, keyAuths);
|
authMap.put(address.getPublicKey(), 1);
|
||||||
AccountUpdateOperation operation = new AccountUpdateOperation(account, owner, active, fee);
|
Authority authority = new Authority(1, authMap, null);
|
||||||
ArrayList<BaseOperation> operations = new ArrayList<BaseOperation>();
|
AccountOptions options = new AccountOptions(address.getPublicKey());
|
||||||
operations.add(operation);
|
BrainKey brainKey = new BrainKey(Main.BILTHON_7_BRAIN_KEY, 0);
|
||||||
Transaction transaction = new Transaction(Main.WIF, blockData, operations);
|
Transaction transaction = new AccountUpdateTransactionBuilder(brainKey.getPrivateKey())
|
||||||
|
.setAccont(new UserAccount("1.2.140994"))
|
||||||
|
.setOwner(authority)
|
||||||
|
.setActive(authority)
|
||||||
|
.setOptions(options)
|
||||||
|
.setBlockData(new BlockData(Main.REF_BLOCK_NUM, Main.REF_BLOCK_PREFIX, Main.RELATIVE_EXPIRATION))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
System.out.println("Json object");
|
||||||
|
System.out.println(transaction.toJsonString());
|
||||||
|
System.out.println("Serialized transaction");
|
||||||
|
System.out.println(Util.bytesToHex(transaction.toBytes()));
|
||||||
} catch(MalformedAddressException e){
|
} catch(MalformedAddressException e){
|
||||||
System.out.println("MalformedAddressException. Msg: "+e.getMessage());
|
System.out.println("MalformedAddressException. Msg: "+e.getMessage());
|
||||||
|
} catch (MalformedTransactionException e) {
|
||||||
|
System.out.println("MalformedTransactionException. Msg: "+e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,18 +734,20 @@ public class Test {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
UserAccount account = new UserAccount("1.2.139313");
|
String newAddress = "BTS8RiFgs8HkcVPVobHLKEv6yL3iXcC9SWjbPVS15dDAXLG9GYhnY";
|
||||||
AssetAmount fee = new AssetAmount(UnsignedLong.valueOf("200"), new Asset("1.3.0"));
|
|
||||||
HashMap<String, Integer> keyAuths = new HashMap<>();
|
|
||||||
keyAuths.put("BTS8RiFgs8HkcVPVobHLKEv6yL3iXcC9SWjbPVS15dDAXLG9GYhnY", 1);
|
|
||||||
try {
|
try {
|
||||||
Authority owner = new Authority(1, keyAuths);
|
Address address = new Address(newAddress);
|
||||||
Authority active = new Authority(1, keyAuths);
|
HashMap<PublicKey, Integer> authMap = new HashMap<>();
|
||||||
AccountUpdateOperation operation = new AccountUpdateOperation(account, owner, active, fee);
|
authMap.put(address.getPublicKey(), 1);
|
||||||
ArrayList<BaseOperation> operations = new ArrayList<BaseOperation>();
|
Authority authority = new Authority(1, authMap, null);
|
||||||
operations.add(operation);
|
AccountOptions options = new AccountOptions(address.getPublicKey());
|
||||||
BrainKey brainKey = new BrainKey(Main.BILTHON_5_BRAIN_KEY, 0);
|
BrainKey brainKey = new BrainKey(Main.BILTHON_7_BRAIN_KEY, 0);
|
||||||
Transaction transaction = new Transaction(brainKey.getWalletImportFormat(), null, operations);
|
Transaction transaction = new AccountUpdateTransactionBuilder(brainKey.getPrivateKey())
|
||||||
|
.setAccont(new UserAccount("1.2.140994"))
|
||||||
|
.setOwner(authority)
|
||||||
|
.setActive(authority)
|
||||||
|
.setOptions(options)
|
||||||
|
.build();
|
||||||
|
|
||||||
SSLContext context = null;
|
SSLContext context = null;
|
||||||
context = NaiveSSLContext.getInstance("TLS");
|
context = NaiveSSLContext.getInstance("TLS");
|
||||||
|
@ -799,8 +760,11 @@ public class Test {
|
||||||
|
|
||||||
mWebSocket.addListener(new TransactionBroadcastSequence(transaction, new Asset("1.3.0"), listener));
|
mWebSocket.addListener(new TransactionBroadcastSequence(transaction, new Asset("1.3.0"), listener));
|
||||||
mWebSocket.connect();
|
mWebSocket.connect();
|
||||||
|
|
||||||
} catch (MalformedAddressException e) {
|
} catch (MalformedAddressException e) {
|
||||||
System.out.println("MalformedAddressException. Msg: "+e.getMessage());
|
System.out.println("MalformedAddressException. Msg: "+e.getMessage());
|
||||||
|
} catch (MalformedTransactionException e) {
|
||||||
|
System.out.println("MalformedTransactionException. Msg: "+e.getMessage());
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
System.out.println("NoSuchAlgorithmException. Msg: "+e.getMessage());
|
System.out.println("NoSuchAlgorithmException. Msg: "+e.getMessage());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -808,5 +772,42 @@ public class Test {
|
||||||
} catch (WebSocketException e) {
|
} catch (WebSocketException e) {
|
||||||
System.out.println("WebSocketException. Msg: "+e.getMessage());
|
System.out.println("WebSocketException. Msg: "+e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// --
|
||||||
|
|
||||||
|
// UserAccount account = new UserAccount("1.2.139313");
|
||||||
|
// AssetAmount fee = new AssetAmount(UnsignedLong.valueOf("200"), new Asset("1.3.0"));
|
||||||
|
// HashMap<String, Integer> keyAuths = new HashMap<>();
|
||||||
|
// keyAuths.put("BTS8RiFgs8HkcVPVobHLKEv6yL3iXcC9SWjbPVS15dDAXLG9GYhnY", 1);
|
||||||
|
// try {
|
||||||
|
// Authority owner = new Authority(1, keyAuths);
|
||||||
|
// Authority active = new Authority(1, keyAuths);
|
||||||
|
// AccountUpdateOperation operation = new AccountUpdateOperation(account, owner, active, null, fee);
|
||||||
|
// ArrayList<BaseOperation> operations = new ArrayList<BaseOperation>();
|
||||||
|
// operations.add(operation);
|
||||||
|
// BrainKey brainKey = new BrainKey(Main.BILTHON_5_BRAIN_KEY, 0);
|
||||||
|
// Transaction transaction = new Transaction(brainKey.getWalletImportFormat(), null, operations);
|
||||||
|
//
|
||||||
|
// SSLContext context = null;
|
||||||
|
// context = NaiveSSLContext.getInstance("TLS");
|
||||||
|
// WebSocketFactory factory = new WebSocketFactory();
|
||||||
|
//
|
||||||
|
// // Set the custom SSL context.
|
||||||
|
// factory.setSSLContext(context);
|
||||||
|
//
|
||||||
|
// WebSocket mWebSocket = factory.createSocket(OPENLEDGER_WITNESS_URL);
|
||||||
|
//
|
||||||
|
// mWebSocket.addListener(new TransactionBroadcastSequence(transaction, new Asset("1.3.0"), listener));
|
||||||
|
// mWebSocket.connect();
|
||||||
|
// } catch (MalformedAddressException e) {
|
||||||
|
// System.out.println("MalformedAddressException. Msg: "+e.getMessage());
|
||||||
|
// } catch (NoSuchAlgorithmException e) {
|
||||||
|
// System.out.println("NoSuchAlgorithmException. Msg: "+e.getMessage());
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// System.out.println("IOException. Msg: "+e.getMessage());
|
||||||
|
// } catch (WebSocketException e) {
|
||||||
|
// System.out.println("WebSocketException. Msg: "+e.getMessage());
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ import java.util.List;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to represent a generic graphene transaction.
|
* Class used to represent a generic Graphene transaction.
|
||||||
*/
|
*/
|
||||||
public class Transaction implements ByteSerializable, JsonSerializable {
|
public class Transaction implements ByteSerializable, JsonSerializable {
|
||||||
private final String TAG = this.getClass().getName();
|
private final String TAG = this.getClass().getName();
|
||||||
|
@ -65,10 +65,18 @@ public class Transaction implements ByteSerializable, JsonSerializable {
|
||||||
this(DumpedPrivateKey.fromBase58(null, wif).getKey(), block_data, operation_list);
|
this(DumpedPrivateKey.fromBase58(null, wif).getKey(), block_data, operation_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the block data
|
||||||
|
* @param blockData: New block data
|
||||||
|
*/
|
||||||
public void setBlockData(BlockData blockData){
|
public void setBlockData(BlockData blockData){
|
||||||
this.blockData = blockData;
|
this.blockData = blockData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the fees for all operations in this transaction.
|
||||||
|
* @param fees: New fees to apply
|
||||||
|
*/
|
||||||
public void setFees(List<AssetAmount> fees){
|
public void setFees(List<AssetAmount> fees){
|
||||||
for(int i = 0; i < operations.size(); i++)
|
for(int i = 0; i < operations.size(); i++)
|
||||||
operations.get(i).setFee(fees.get(i));
|
operations.get(i).setFee(fees.get(i));
|
||||||
|
|
|
@ -11,5 +11,16 @@ public abstract class TransactionBuilder {
|
||||||
protected ECKey privateKey;
|
protected ECKey privateKey;
|
||||||
protected BlockData blockData;
|
protected BlockData blockData;
|
||||||
|
|
||||||
|
public TransactionBuilder(){}
|
||||||
|
|
||||||
|
public TransactionBuilder(ECKey privKey){
|
||||||
|
this.privateKey = privKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionBuilder setBlockData(BlockData blockData){
|
||||||
|
this.blockData = blockData;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract Transaction build() throws MalformedTransactionException;
|
public abstract Transaction build() throws MalformedTransactionException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,12 @@ public class TransferTransactionBuilder extends TransactionBuilder {
|
||||||
private AssetAmount transferAmount;
|
private AssetAmount transferAmount;
|
||||||
private AssetAmount feeAmount;
|
private AssetAmount feeAmount;
|
||||||
|
|
||||||
|
public TransferTransactionBuilder(){}
|
||||||
|
|
||||||
|
public TransferTransactionBuilder(ECKey privKey) {
|
||||||
|
super(privKey);
|
||||||
|
}
|
||||||
|
|
||||||
public TransferTransactionBuilder setPrivateKey(ECKey key){
|
public TransferTransactionBuilder setPrivateKey(ECKey key){
|
||||||
this.privateKey = key;
|
this.privateKey = key;
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -15,6 +15,8 @@ import java.io.IOException;
|
||||||
*/
|
*/
|
||||||
public class UserAccount extends GrapheneObject implements ByteSerializable, JsonSerializable {
|
public class UserAccount extends GrapheneObject implements ByteSerializable, JsonSerializable {
|
||||||
|
|
||||||
|
public static final String PROXY_TO_SELF = "1.2.5";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor that expects a user account in the string representation.
|
* Constructor that expects a user account in the string representation.
|
||||||
* That is in the 1.2.x format.
|
* That is in the 1.2.x format.
|
||||||
|
|
33
src/main/java/com/luminiasoft/bitshares/Vote.java
Normal file
33
src/main/java/com/luminiasoft/bitshares/Vote.java
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package com.luminiasoft.bitshares;
|
||||||
|
|
||||||
|
import com.luminiasoft.bitshares.interfaces.ByteSerializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by nelson on 12/5/16.
|
||||||
|
*/
|
||||||
|
public class Vote implements ByteSerializable {
|
||||||
|
private int type;
|
||||||
|
private int instance;
|
||||||
|
|
||||||
|
public Vote(String vote){
|
||||||
|
String[] parts = vote.split(":");
|
||||||
|
assert(parts.length == 2);
|
||||||
|
this.type = Integer.valueOf(parts[0]);
|
||||||
|
this.instance = Integer.valueOf(parts[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vote(int type, int instance){
|
||||||
|
this.type = type;
|
||||||
|
this.instance = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("%d:%d", this.type, this.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] toBytes() {
|
||||||
|
return new byte[] { (byte) this.instance, (byte) this.type };
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.luminiasoft.bitshares.interfaces;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface used to group both ByteSerializable and JsonSerializable interfaces.
|
||||||
|
*/
|
||||||
|
public interface GrapheneSerializable extends ByteSerializable, JsonSerializable {
|
||||||
|
}
|
|
@ -5,7 +5,8 @@ import com.google.gson.JsonElement;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to be implemented by any entity for which makes sense to have a JSON-formatted string representation.
|
* Interface to be implemented by any entity for which makes sense to
|
||||||
|
* have a JSON-formatted string and object representation.
|
||||||
*/
|
*/
|
||||||
public interface JsonSerializable extends Serializable {
|
public interface JsonSerializable extends Serializable {
|
||||||
|
|
||||||
|
|
|
@ -142,12 +142,17 @@ public class TransactionBroadcastSequence 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. cause: "+cause.getMessage());
|
||||||
mListener.onError(new BaseResponse.Error(cause.getMessage()));
|
mListener.onError(new BaseResponse.Error(cause.getMessage()));
|
||||||
websocket.disconnect();
|
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. cause: "+cause.getMessage()+", error: "+cause.getClass());
|
||||||
|
for (StackTraceElement element : cause.getStackTrace()){
|
||||||
|
System.out.println(element.getFileName()+"#"+element.getClassName()+":"+element.getLineNumber());
|
||||||
|
}
|
||||||
mListener.onError(new BaseResponse.Error(cause.getMessage()));
|
mListener.onError(new BaseResponse.Error(cause.getMessage()));
|
||||||
websocket.disconnect();
|
websocket.disconnect();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue