added more documentation

This commit is contained in:
pinpong 2017-02-05 13:43:06 +01:00
parent 8e08047b93
commit cdea177ebd
12 changed files with 144 additions and 80 deletions

View File

@ -47,7 +47,7 @@ public class IotaAPI extends IotaAPICore {
* @param returnAll If true, it returns all addresses which were deterministically generated (until findTransactions returns null)
* @return an array of strings with the specifed number of addresses
*/
public GetNewAddressResponse getNewAddress(final String seed, int security, final int index, final boolean checksum, final int total, final boolean returnAll) throws InvalidSecurityLevelException {
public GetNewAddressResponse getNewAddress(final String seed, int security, final int index, final boolean checksum, final int total, final boolean returnAll) throws InvalidSecurityLevelException, InvalidAddressException {
if (security < 1 || security > 3) {
throw new InvalidSecurityLevelException();
@ -95,7 +95,7 @@ public class IotaAPI extends IotaAPICore {
* @param inclusionStates Optional (default false). If True, it gets the inclusion states of the transfers.
* @return Bundle
**/
public GetTransferResponse getTransfers(String seed, int security, Integer start, Integer end, Boolean inclusionStates) throws ArgumentException, InvalidBundleException, InvalidSignatureException, NoNodeInfoException, NoInclusionStatesExcpection, InvalidSecurityLevelException {
public GetTransferResponse getTransfers(String seed, int security, Integer start, Integer end, Boolean inclusionStates) throws ArgumentException, InvalidBundleException, InvalidSignatureException, NoNodeInfoException, NoInclusionStatesExcpection, InvalidSecurityLevelException, InvalidAddressException {
StopWatch stopWatch = new StopWatch();
// validate & if needed pad seed
if ((seed = InputValidator.validateSeed(seed)) == null) {
@ -113,12 +113,9 @@ public class IotaAPI extends IotaAPICore {
}
StopWatch sw = new StopWatch();
System.out.println("GetTransfer started");
GetNewAddressResponse gnr = getNewAddress(seed, security, start, false, end, true);
if (gnr != null && gnr.getAddresses() != null) {
System.out.println("GetTransfers after getNewAddresses " + sw.getElapsedTimeMili() + " ms");
Bundle[] bundles = bundlesFromAddresses(gnr.getAddresses().toArray(new String[gnr.getAddresses().size()]), inclusionStates);
System.out.println("GetTransfers after bundlesFromAddresses " + sw.getElapsedTimeMili() + " ms");
return GetTransferResponse.create(bundles, stopWatch.getElapsedTimeMili());
}
return GetTransferResponse.create(new Bundle[]{}, stopWatch.getElapsedTimeMili());
@ -321,11 +318,11 @@ public class IotaAPI extends IotaAPICore {
* @param inputs the inputs
* @return trytes Returns bundle trytes
**/
public List<String> prepareTransfers(String seed, int security, final List<Transfer> transfers, String remainder, List<Input> inputs) throws NotEnoughBalanceException, InvalidSecurityLevelException {
public List<String> prepareTransfers(String seed, int security, final List<Transfer> transfers, String remainder, List<Input> inputs) throws NotEnoughBalanceException, InvalidSecurityLevelException, InvalidAddressException, InvalidTransferException {
// Input validation of transfers object
if (!InputValidator.isTransfersCollectionCorrect(transfers)) {
throw new IllegalStateException("Invalid Transfer");
throw new InvalidTransferException();
}
// validate & if needed pad seed
@ -479,7 +476,7 @@ public class IotaAPI extends IotaAPICore {
* @param end end Ending key index
* @param threshold threshold Min balance required
**/
public GetBalancesAndFormatResponse getInputs(String seed, int security, int start, int end, long threshold) throws InvalidSecurityLevelException {
public GetBalancesAndFormatResponse getInputs(String seed, int security, int start, int end, long threshold) throws InvalidSecurityLevelException, InvalidAddressException {
StopWatch stopWatch = new StopWatch();
// validate the seed
if (!InputValidator.isTrytes(seed, 0)) {
@ -725,7 +722,7 @@ public class IotaAPI extends IotaAPICore {
* @return array of Transaction objects
**/
public SendTransferResponse sendTransfer(String seed, int security, int depth, int minWeightMagnitude, final List<Transfer> transfers, Input[] inputs, String address) throws NotEnoughBalanceException, InvalidSecurityLevelException, InvalidTrytesException {
public SendTransferResponse sendTransfer(String seed, int security, int depth, int minWeightMagnitude, final List<Transfer> transfers, Input[] inputs, String address) throws NotEnoughBalanceException, InvalidSecurityLevelException, InvalidTrytesException, InvalidAddressException, InvalidTransferException {
if (security < 1 || security > 3) {
throw new InvalidSecurityLevelException();
@ -804,12 +801,12 @@ public class IotaAPI extends IotaAPICore {
* Prepares transfer by generating the bundle with the corresponding cosigner transactions
* Does not contain signatures
*
* @param securitySum sum of security levels used by all co-signers
* @param inputAddress array of input addresses as well as the securitySum
* @param remainderAddress Has to be generated by the cosigners before initiating the transfer, can be null if fully spent
* @param securitySum sum of security levels used by all co-signers
* @param inputAddress array of input addresses as well as the securitySum
* @param remainderAddress has to be generated by the cosigners before initiating the transfer, can be null if fully spent
* @return bundle of transaction objects
**/
private GetTransferResponse initiateTransfer(int securitySum, final List<String> inputAddress, String remainderAddress, final List<Transfer> transfers) {
private GetTransferResponse initiateTransfer(int securitySum, final List<String> inputAddress, String remainderAddress, final List<Transfer> transfers) throws InvalidAddressException, InvalidBundleException, InvalidTransferException {
StopWatch sw = new StopWatch();
@ -828,19 +825,19 @@ public class IotaAPI extends IotaAPICore {
// Input validation of transfers object
if (!InputValidator.isTransfersCollectionCorrect(transfers)) {
throw new IllegalStateException("Invalid Transfer");
throw new InvalidTransferException();
}
// validate input address
for (String address : inputAddress) {
if (!InputValidator.isAddress(address))
throw new IllegalStateException("Invalid Address");
throw new InvalidBundleException();
}
// validate remainder address
if (remainderAddress != null && !InputValidator.isAddress(remainderAddress)) {
throw new IllegalStateException("Invalid Address");
throw new InvalidBundleException();
}
// Create a new bundle
@ -989,7 +986,7 @@ public class IotaAPI extends IotaAPICore {
final String tag,
final long totalValue,
final String remainderAddress,
final List<String> signatureFragments) throws NotEnoughBalanceException, InvalidSecurityLevelException {
final List<String> signatureFragments) throws NotEnoughBalanceException, InvalidSecurityLevelException, InvalidAddressException {
long totalTransferValue = totalValue;
for (int i = 0; i < inputs.size(); i++) {

View File

@ -0,0 +1,10 @@
package jota.error;
/**
* Created by pinpong on 05.02.17.
*/
public class InvalidAddressException extends BaseException {
public InvalidAddressException() {
super("Invalid Address!");
}
}

View File

@ -0,0 +1,10 @@
package jota.error;
/**
* Created by pinpong on 05.02.17.
*/
public class InvalidTransferException extends BaseException {
public InvalidTransferException() {
super("Invalid Transfer!");
}
}

View File

@ -1,5 +1,6 @@
package jota.utils;
import jota.error.InvalidAddressException;
import jota.pow.JCurl;
/**
@ -13,7 +14,7 @@ public class Checksum {
* @param address address without checksum
* @return the address with the appended checksum
**/
public static String addChecksum(String address) {
public static String addChecksum(String address) throws InvalidAddressException {
InputValidator.checkAddress(address);
String addressWithChecksum = address;
addressWithChecksum += calculateChecksum(address);
@ -26,11 +27,11 @@ public class Checksum {
* @param address address with checksum
* @return the address without checksum
**/
public static String removeChecksum(String address) {
public static String removeChecksum(String address) throws InvalidAddressException {
if (isAddressWithChecksum(address)) {
return getAddress(address);
}
throw new RuntimeException("Invalid address: " + address);
throw new InvalidAddressException();
}
/**
@ -49,7 +50,7 @@ public class Checksum {
* @param addressWithChecksum address
* @return boolean
**/
public static boolean isValidChecksum(String addressWithChecksum) {
public static boolean isValidChecksum(String addressWithChecksum) throws InvalidAddressException {
String addressWithoutChecksum = removeChecksum(addressWithChecksum);
String addressWithRecalculateChecksum = addressWithChecksum += calculateChecksum(addressWithoutChecksum);
return addressWithRecalculateChecksum.equals(addressWithChecksum);
@ -62,7 +63,7 @@ public class Checksum {
* @param address address
* @return boolean
**/
public static boolean isAddressWithChecksum(String address) {
public static boolean isAddressWithChecksum(String address) throws InvalidAddressException {
return InputValidator.checkAddress(address) && address.length() == Constants.ADDRESS_LENGTH_WITH_CHECKSUM;
}
@ -73,7 +74,7 @@ public class Checksum {
* @param address address
* @return boolean
**/
public static boolean isAddressWithoutChecksum(String address) {
public static boolean isAddressWithoutChecksum(String address) throws InvalidAddressException {
return InputValidator.checkAddress(address) && address.length() == Constants.ADDRESS_LENGTH_WITHOUT_CHECKSUM;
}

View File

@ -90,6 +90,12 @@ public class Converter {
return d;
}
/**
* Converts trytes into trits
*
* @param trytes trytes to be converted
* @return array of trits
**/
public static int[] trits(final String trytes) {
final List<Integer> trits = new LinkedList<>();
if (InputValidator.isValue(trytes)) {
@ -160,6 +166,14 @@ public class Converter {
return destination;
}
/**
* Converts trites to trytes
*
* @param trits trits to be converted
* @param offset
* @param size
* @return trytes
**/
public static String trytes(final int[] trits, final int offset, final int size) {
StringBuilder trytes = new StringBuilder();

View File

@ -1,5 +1,6 @@
package jota.utils;
import jota.error.InvalidAddressException;
import jota.model.Transfer;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
@ -28,9 +29,9 @@ public class InputValidator {
* @param address address to validate
* @return boolean
**/
public static boolean checkAddress(String address) {
public static boolean checkAddress(String address) throws InvalidAddressException {
if (!isAddress(address)) {
throw new RuntimeException("Invalid address: " + address);
throw new InvalidAddressException();
}
return true;
}
@ -70,7 +71,7 @@ public class InputValidator {
/**
* determines whether the specified string represents a signed integer
*
* @param value the value
* @param trytes the trytes
* @return boolean
**/
public static boolean isArrayOfTrytes(String[] trytes){
@ -83,6 +84,12 @@ public class InputValidator {
return true;
}
/**
* checks if input is array of hashes
*
* @param hashes
* @return boolean
**/
public static boolean isArrayOfHashes(String[] hashes) {
if (hashes == null)
return false;
@ -105,21 +112,26 @@ public class InputValidator {
/**
* checks if input is correct hash collections
*
* @param {array} hash
* @method isTransfersArray
* @returns {boolean}
* @param transfers
* @return boolean
**/
public static boolean isTransfersCollectionCorrect(final List<Transfer> transfers) {
for (final Transfer transfer : transfers) {
if (!isTransfersArray(transfer)) {
if (!isTransfer(transfer)) {
return false;
}
}
return true;
}
public static boolean isTransfersArray(final Transfer transfer) {
/**
* checks if input is correct transfer
*
* @param transfer
* @return boolean
**/
public static boolean isTransfer(final Transfer transfer) {
if (!isAddress(transfer.getAddress())) {
return false;

View File

@ -1,5 +1,6 @@
package jota.utils;
import jota.error.InvalidAddressException;
import jota.model.Bundle;
import jota.model.Input;
import jota.model.Transaction;
@ -20,13 +21,14 @@ public class IotaAPIUtils {
/**
* Generates a new address
*
* @param seed
* @param index
* @param security
* @param checksum
* @param seed tryte-encoded seed. It should be noted that this seed is not transferred
* @param security security secuirty level of private key / seed
* @param index key index to start search from. If the index is provided, the generation of the address is not deterministic.
* @param checksum adds 9-tryte address checksum
* @param curl
* @return an String with address
*/
public static String newAddress(String seed, int security, int index, boolean checksum, ICurl curl) {
public static String newAddress(String seed, int security, int index, boolean checksum, ICurl curl) throws InvalidAddressException {
Signing signing = new Signing(curl);
final int[] key = signing.key(Converter.trits(seed), index, security);
final int[] digests = signing.digests(key);

View File

@ -20,6 +20,13 @@ public class IotaUnitConverter {
return convertUnits(amountInSource, toUnit);
}
/**
* convert unit
*
* @param amount the amount
* @param toUnit the target unit
* @return the specified amount in the target unit
**/
private static long convertUnits(long amount, IotaUnits toUnit) {
return (long) (amount / Math.pow(10, toUnit.getValue()));
}
@ -37,16 +44,38 @@ public class IotaUnitConverter {
return createAmountWithUnitDisplayText(amountInDisplayUnit, unit, extended);
}
/**
* convert amount to target unit
*
* @param amount the amount
* @return the target unit
**/
public static double convertAmountTo(long amount, IotaUnits target) {
return amount / Math.pow(10, target.getValue());
}
/**
* create amount with unit text
*
* @param amountInUnit the amount in units
* @param unit the unit
* @param extended extended length
* @return the target unit
**/
private static String createAmountWithUnitDisplayText(double amountInUnit, IotaUnits unit, boolean extended) {
String result = createAmountDisplayText(amountInUnit, unit, extended);
result += " " + unit.getUnit();
return result;
}
/**
* create amount text
*
* @param amountInUnit the amount in units
* @param unit the unit
* @param extended extended length
* @return the target unit
**/
public static String createAmountDisplayText(double amountInUnit, IotaUnits unit, boolean extended) {
DecimalFormat df;
if (extended) df = new DecimalFormat("##0.##################");

View File

@ -24,17 +24,14 @@ public class Multisig {
}
/**
* Gets the digest value of a seed
*
* @param {string} seed
* @param {int} index
* @param {int} security
* @method getDigest
* @returns {string} digest trytes
* @param seed tryte-encoded seed. It should be noted that this seed is not transferred
* @param security security secuirty level of private key / seed
* @param index
* @return digest trytes
**/
private String getDigest(String seed, int index, int security) {
private String getDigest(String seed, int security, int index) {
int[] key = signingInstance.key(Converter.trits(seed), index, security);
int[] key = signingInstance.key(Converter.trits(seed), security, index);
return Converter.trytes(signingInstance.digests(key));
}
@ -44,7 +41,7 @@ public class Multisig {
* @param digestTrytes
* @param curlStateTrytes
* @method addAddressDigest
* @returns {String}
* @return digest trytes
**/
private String addAddressDigest(String digestTrytes, String curlStateTrytes, ICurl customCurl) {
@ -70,10 +67,9 @@ public class Multisig {
/**
* Gets the key value of a seed
*
* @param {string} seed
* @param {int} index
* @method getKey
* @returns {string} digest trytes
* @param seed tryte-encoded seed. It should be noted that this seed is not transferred
* @param index
* @return digest trytes
**/
private String getKey(String seed, int index, int security) {
@ -84,10 +80,9 @@ public class Multisig {
/**
* Generates a new address
*
* @param {string} curlStateTrytes
* @param {string}
* @method finalizeAddress
* @returns {String} address
* @param curlStateTrytes
* @param customCurl
* @return address
**/
private String finalizeAddress(String curlStateTrytes, ICurl customCurl) {
@ -108,8 +103,8 @@ public class Multisig {
*
* @param multisigAddress
* @param digests
* @method validateAddress
* @returns {bool}
* @param customCurl
* @returns boolean
**/
private boolean validateAddress(String multisigAddress, int[][] digests, ICurl customCurl) {
@ -131,13 +126,10 @@ public class Multisig {
/**
* Adds the cosigner signatures to the corresponding bundle transaction
*
* @param {array} bundleToSign
* @param {int} cosignerIndex
* @param {string} inputAddress
* @param {string} key
* @param {function} callback
* @method addSignature
* @returns {array} trytes Returns bundle trytes
* @param bundleToSign
* @param inputAddress
* @param keyTrytes
* @return trytes Returns bundle trytes
**/
private void addSignature(Bundle[] bundleToSign, String inputAddress, String keyTrytes) {

View File

@ -1,5 +1,6 @@
package jota;
import jota.error.InvalidAddressException;
import jota.utils.Checksum;
import org.junit.Test;
@ -14,17 +15,17 @@ public class ChecksumTest {
private static final String TEST_ADDRESS_WITH_CHECKSUM = "RVORZ9SIIP9RCYMREUIXXVPQIPHVCNPQ9HZWYKFWYWZRE9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVAFOXM9MUBX";
@Test
public void shouldAddChecksum() {
public void shouldAddChecksum() throws InvalidAddressException {
assertEquals(Checksum.addChecksum(TEST_ADDRESS_WITHOUT_CHECKSUM), TEST_ADDRESS_WITH_CHECKSUM);
}
@Test
public void shouldRemoveChecksum() {
public void shouldRemoveChecksum() throws InvalidAddressException {
assertEquals(Checksum.removeChecksum(TEST_ADDRESS_WITH_CHECKSUM), TEST_ADDRESS_WITHOUT_CHECKSUM);
}
@Test
public void shouldIsValidChecksum() {
public void shouldIsValidChecksum() throws InvalidAddressException {
assertEquals(Checksum.isValidChecksum(TEST_ADDRESS_WITH_CHECKSUM), true);
}
}

View File

@ -1,5 +1,6 @@
package jota;
import jota.error.InvalidAddressException;
import jota.model.Transfer;
import jota.utils.InputValidator;
import org.junit.Test;
@ -27,7 +28,7 @@ public class InputValidatorTest {
}
@Test
public void shouldCheckAddress() {
public void shouldCheckAddress() throws InvalidAddressException {
assertEquals(InputValidator.checkAddress(TEST_ADDRESS_WITHOUT_CHECKSUM), true);
}

View File

@ -75,7 +75,7 @@ public class IotaAPITest {
@Test
public void shouldGetInputs() throws InvalidSecurityLevelException {
public void shouldGetInputs() throws InvalidSecurityLevelException, InvalidAddressException {
GetBalancesAndFormatResponse res = iotaClient.getInputs(TEST_SEED1, 2, 0, 0, 0);
System.out.println(res);
assertThat(res, IsNull.notNullValue());
@ -85,7 +85,7 @@ public class IotaAPITest {
}
@Test
public void shouldCreateANewAddressWithoutChecksum() throws InvalidSecurityLevelException {
public void shouldCreateANewAddressWithoutChecksum() throws InvalidSecurityLevelException, InvalidAddressException {
final GetNewAddressResponse res1 = iotaClient.getNewAddress(TEST_SEED1, 1, 0, false, 5, false);
assertThat(res1.getAddresses().get(0), Is.is(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_1));
@ -97,16 +97,11 @@ public class IotaAPITest {
}
@Test
public void shouldPrepareTransfer() throws InvalidSecurityLevelException {
public void shouldPrepareTransfer() throws InvalidSecurityLevelException, NotEnoughBalanceException, InvalidAddressException, InvalidTransferException {
List<Transfer> transfers = new ArrayList<>();
transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2, 0, TEST_MESSAGE, TEST_TAG));
transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2, 1, TEST_MESSAGE, TEST_TAG));
List<String> trytes = null;
try {
trytes = iotaClient.prepareTransfers(TEST_SEED1, 2, transfers, null, null);
} catch (NotEnoughBalanceException e) {
e.printStackTrace();
}
List<String> trytes = iotaClient.prepareTransfers(TEST_SEED1, 2, transfers, null, null);
Assert.assertNotNull(trytes);
assertThat(trytes.isEmpty(), Is.is(false));
}
@ -136,7 +131,7 @@ public class IotaAPITest {
}
@Test
public void shouldGetTransfers() throws InvalidBundleException, ArgumentException, InvalidSignatureException, NoInclusionStatesExcpection, NoNodeInfoException, InvalidSecurityLevelException {
public void shouldGetTransfers() throws InvalidBundleException, ArgumentException, InvalidSignatureException, NoInclusionStatesExcpection, NoNodeInfoException, InvalidSecurityLevelException, InvalidAddressException {
GetTransferResponse gtr = iotaClient.getTransfers(TEST_SEED1, 2, 0, 0, false);
assertThat(gtr.getTransfers(), IsNull.notNullValue());
@ -159,17 +154,17 @@ public class IotaAPITest {
iotaClient.sendTrytes(new String[]{TEST_TRYTES}, 9, 18);
}
@Ignore
@Test(expected = IllegalStateException.class)
public void shouldNotSendTransfer() throws ArgumentException, InvalidSignatureException, InvalidBundleException, NotEnoughBalanceException, InvalidSecurityLevelException, InvalidTrytesException {
public void shouldNotSendTransfer() throws ArgumentException, InvalidSignatureException, InvalidBundleException, NotEnoughBalanceException, InvalidSecurityLevelException, InvalidTrytesException, InvalidAddressException, InvalidTransferException {
List<Transfer> transfers = new ArrayList<>();
transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2, 10000990, "JUSTANOTHERTEST", TEST_TAG));
SendTransferResponse str = iotaClient.sendTransfer(TEST_SEED2, 2, 9, 18, transfers, null, null);
assertThat(str.getSuccessfully(), IsNull.notNullValue());
}
@Ignore
@Test
public void shouldSendTransfer() throws ArgumentException, InvalidSignatureException, InvalidBundleException, NotEnoughBalanceException, InvalidSecurityLevelException, InvalidTrytesException {
public void shouldSendTransfer() throws ArgumentException, InvalidSignatureException, InvalidBundleException, NotEnoughBalanceException, InvalidSecurityLevelException, InvalidTrytesException, InvalidAddressException, InvalidTransferException {
List<Transfer> transfers = new ArrayList<>();
transfers.add(new jota.model.Transfer(TEST_ADDRESS_WITHOUT_CHECKSUM_SECURITY_LEVEL_2, 0, "JUSTANOTHERTEST", TEST_TAG));
SendTransferResponse str = iotaClient.sendTransfer(TEST_SEED2, 2, 9, 18, transfers, null, null);