use of jota.pow.ICurl in project run-wallet-android by runplay.
the class IotaMsg method getBundle.
/**
* Gets the associated bundle transactions of a single transaction.
* Does validation of signatures, total sum as well as bundle order.
*
* @param transaction The transaction encoded in trytes.
* @return an array of bundle, if there are multiple arrays it means that there are conflicting bundles.
* @throws ArgumentException is thrown when the specified input is not valid.
*/
public GetBundleResponse getBundle(String transaction) throws ArgumentException {
if (!InputValidator.isHash(transaction)) {
throw new ArgumentException(INVALID_HASHES_INPUT_ERROR);
}
Bundle bundle = traverseBundle(transaction, null, new Bundle());
if (bundle == null) {
throw new ArgumentException(INVALID_BUNDLE_ERROR);
}
StopWatch stopWatch = new StopWatch();
long totalSum = 0;
String bundleHash = bundle.getTransactions().get(0).getBundle();
ICurl curl = SpongeFactory.create(SpongeFactory.Mode.KERL);
curl.reset();
List<Signature> signaturesToValidate = new ArrayList<>();
for (int i = 0; i < bundle.getTransactions().size(); i++) {
Transaction trx = bundle.getTransactions().get(i);
Long bundleValue = trx.getValue();
totalSum += bundleValue;
if (i != bundle.getTransactions().get(i).getCurrentIndex()) {
throw new ArgumentException(INVALID_BUNDLE_ERROR);
}
String trxTrytes = trx.toTrytes().substring(2187, 2187 + 162);
// Absorb bundle hash + value + timestamp + lastIndex + currentIndex trytes.
curl.absorb(Converter.trits(trxTrytes));
// Check if input transaction
if (bundleValue < 0) {
String address = trx.getAddress();
Signature sig = new Signature();
sig.setAddress(address);
sig.getSignatureFragments().add(trx.getSignatureFragments());
// Find the subsequent txs with the remaining signature fragment
for (int y = i + 1; y < bundle.getTransactions().size(); y++) {
Transaction newBundleTx = bundle.getTransactions().get(y);
// Check if new tx is part of the signature fragment
if (newBundleTx.getAddress().equals(address) && newBundleTx.getValue() == 0) {
if (sig.getSignatureFragments().indexOf(newBundleTx.getSignatureFragments()) == -1)
sig.getSignatureFragments().add(newBundleTx.getSignatureFragments());
}
}
signaturesToValidate.add(sig);
}
}
// Check for total sum, if not equal 0 return error
if (totalSum != 0)
throw new ArgumentException(INVALID_BUNDLE_SUM_ERROR);
int[] bundleFromTrxs = new int[243];
curl.squeeze(bundleFromTrxs);
String bundleFromTxString = Converter.trytes(bundleFromTrxs);
// Check if bundle hash is the same as returned by tx object
if (!bundleFromTxString.equals(bundleHash))
throw new ArgumentException(INVALID_BUNDLE_HASH_ERROR);
// Last tx in the bundle should have currentIndex === lastIndex
bundle.setLength(bundle.getTransactions().size());
if (!(bundle.getTransactions().get(bundle.getLength() - 1).getCurrentIndex() == (bundle.getTransactions().get(bundle.getLength() - 1).getLastIndex())))
throw new ArgumentException(INVALID_BUNDLE_ERROR);
// Validate the signatures
for (Signature aSignaturesToValidate : signaturesToValidate) {
String[] signatureFragments = aSignaturesToValidate.getSignatureFragments().toArray(new String[aSignaturesToValidate.getSignatureFragments().size()]);
String address = aSignaturesToValidate.getAddress();
boolean isValidSignature = new Signing(customCurl.clone()).validateSignatures(address, signatureFragments, bundleHash);
if (!isValidSignature)
throw new ArgumentException(INVALID_SIGNATURES_ERROR);
}
return GetBundleResponse.create(bundle.getTransactions(), stopWatch.getElapsedTimeMili());
}
use of jota.pow.ICurl in project run-wallet-android by runplay.
the class RunIotaAPI method getBundle.
/**
* Gets the associated bundle transactions of a single transaction.
* Does validation of signatures, total sum as well as bundle order.
*
* @param transaction The transaction encoded in trytes.
* @return an array of bundle, if there are multiple arrays it means that there are conflicting bundles.
* @throws ArgumentException is thrown when the specified input is not valid.
*/
public GetBundleResponse getBundle(String transaction) throws ArgumentException {
if (!InputValidator.isHash(transaction)) {
throw new ArgumentException(INVALID_HASHES_INPUT_ERROR);
}
Bundle bundle = traverseBundle(transaction, null, new Bundle());
if (bundle == null) {
throw new ArgumentException(INVALID_BUNDLE_ERROR);
}
StopWatch stopWatch = new StopWatch();
long totalSum = 0;
String bundleHash = bundle.getTransactions().get(0).getBundle();
ICurl curl = SpongeFactory.create(SpongeFactory.Mode.KERL);
curl.reset();
List<Signature> signaturesToValidate = new ArrayList<>();
for (int i = 0; i < bundle.getTransactions().size(); i++) {
Transaction trx = bundle.getTransactions().get(i);
Long bundleValue = trx.getValue();
totalSum += bundleValue;
if (i != bundle.getTransactions().get(i).getCurrentIndex()) {
throw new ArgumentException(INVALID_BUNDLE_ERROR);
}
String trxTrytes = trx.toTrytes().substring(2187, 2187 + 162);
// Absorb bundle hash + value + timestamp + lastIndex + currentIndex trytes.
curl.absorb(Converter.trits(trxTrytes));
// Check if input transaction
if (bundleValue < 0) {
String address = trx.getAddress();
Signature sig = new Signature();
sig.setAddress(address);
sig.getSignatureFragments().add(trx.getSignatureFragments());
// Find the subsequent txs with the remaining signature fragment
for (int y = i + 1; y < bundle.getTransactions().size(); y++) {
Transaction newBundleTx = bundle.getTransactions().get(y);
// Check if new tx is part of the signature fragment
if (newBundleTx.getAddress().equals(address) && newBundleTx.getValue() == 0) {
if (sig.getSignatureFragments().indexOf(newBundleTx.getSignatureFragments()) == -1)
sig.getSignatureFragments().add(newBundleTx.getSignatureFragments());
}
}
signaturesToValidate.add(sig);
}
}
// Check for total sum, if not equal 0 return error
if (totalSum != 0)
throw new ArgumentException(INVALID_BUNDLE_SUM_ERROR);
int[] bundleFromTrxs = new int[243];
curl.squeeze(bundleFromTrxs);
String bundleFromTxString = Converter.trytes(bundleFromTrxs);
// Check if bundle hash is the same as returned by tx object
if (!bundleFromTxString.equals(bundleHash))
throw new ArgumentException(INVALID_BUNDLE_HASH_ERROR);
// Last tx in the bundle should have currentIndex === lastIndex
bundle.setLength(bundle.getTransactions().size());
if (!(bundle.getTransactions().get(bundle.getLength() - 1).getCurrentIndex() == (bundle.getTransactions().get(bundle.getLength() - 1).getLastIndex())))
throw new ArgumentException(INVALID_BUNDLE_ERROR);
// Validate the signatures
for (Signature aSignaturesToValidate : signaturesToValidate) {
String[] signatureFragments = aSignaturesToValidate.getSignatureFragments().toArray(new String[aSignaturesToValidate.getSignatureFragments().size()]);
String address = aSignaturesToValidate.getAddress();
boolean isValidSignature = new Signing(customCurl.clone()).validateSignatures(address, signatureFragments, bundleHash);
if (!isValidSignature)
throw new ArgumentException(INVALID_SIGNATURES_ERROR);
}
return GetBundleResponse.create(bundle.getTransactions(), stopWatch.getElapsedTimeMili());
}
Aggregations