Fix send bad request

Change Send manager to send only the required amount from gtxio
added error capture for estimatefee
This commit is contained in:
hvarona 2018-11-30 20:58:13 -04:00
parent 618e71a6ac
commit 08df53730b
6 changed files with 115 additions and 83 deletions

View file

@ -35,14 +35,18 @@ public abstract class GetEstimateFee {
call.enqueue(new Callback<JsonObject>() { call.enqueue(new Callback<JsonObject>() {
@Override @Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) { public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
try {
listener.estimateFee((double) (response.body().get("2").getAsDouble())); listener.estimateFee((double) (response.body().get("2").getAsDouble()));
}catch (Exception e){
e.printStackTrace();
listener.fail();
}
} }
@Override @Override
public void onFailure(Call<JsonObject> call, Throwable t) { public void onFailure(Call<JsonObject> call, Throwable t) {
listener.fail(); listener.fail();
listener.estimateFee(-1);
} }
}); });
}catch(Exception e){ }catch(Exception e){

View file

@ -97,8 +97,8 @@ class InsightApiServiceGenerator {
return chain.proceed(request); return chain.proceed(request);
} }
}); });
sClientBuilder.readTimeout(5, TimeUnit.MINUTES); sClientBuilder.readTimeout(30, TimeUnit.SECONDS);
sClientBuilder.connectTimeout(5, TimeUnit.MINUTES); sClientBuilder.connectTimeout(30, TimeUnit.SECONDS);
OkHttpClient client = sClientBuilder.build(); OkHttpClient client = sClientBuilder.build();
Retrofit retrofit = sBuilder.client(client).build(); Retrofit retrofit = sBuilder.client(client).build();
return retrofit.create(serviceClass); return retrofit.create(serviceClass);

View file

@ -52,8 +52,8 @@ public class CrystalApplication extends Application {
public static final String BITCOIN_SERVER_URLS[] ={ public static final String BITCOIN_SERVER_URLS[] ={
"https://testnet.blockexplorer.com/",
"https://test-insight.bitpay.com", "https://test-insight.bitpay.com",
//"https://testnet.blockexplorer.com/",
//"https://insight.bitpay.com/" //"https://insight.bitpay.com/"
}; };

View file

@ -545,6 +545,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
throwable.printStackTrace(); throwable.printStackTrace();
} }
} else { } else {
crystalDialog.dismiss();
Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG); Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG);
} }
} }
@ -577,6 +578,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
throwable.printStackTrace(); throwable.printStackTrace();
} }
} else { } else {
crystalDialog.dismiss();
Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG); Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG);
} }
} }

View file

@ -241,11 +241,12 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
ccTransaction.setAccountId(address.getAccountId()); ccTransaction.setAccountId(address.getAccountId());
ccTransaction.setFrom(addr); ccTransaction.setFrom(addr);
ccTransaction.setInput(false); ccTransaction.setInput(false);
amount -= (long) (txi.fee * Math.pow(10, cryptoCoin.getPrecision()));
} }
if (ccTransaction.getAccountId() == address.getAccountId()) { //if (ccTransaction.getAccountId() == address.getAccountId()) {
amount -= (long) (vin.value * Math.pow(10, cryptoCoin.getPrecision())); amount -= (long) (vin.value * Math.pow(10, cryptoCoin.getPrecision()));
} //}
} }
if (ccTransaction.getFrom() == null || ccTransaction.getFrom().isEmpty()) { if (ccTransaction.getFrom() == null || ccTransaction.getFrom().isEmpty()) {
@ -280,9 +281,9 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
ccTransaction.setTo(addr); ccTransaction.setTo(addr);
} }
if (ccTransaction.getAccountId() == address.getAccountId()) { //if (ccTransaction.getAccountId() == address.getAccountId()) {
amount += (long) (vout.value * Math.pow(10, cryptoCoin.getPrecision())); amount += (long) (vout.value * Math.pow(10, cryptoCoin.getPrecision()));
} //}
} else { } else {
//TOOD multiple send address //TOOD multiple send address
if (ccTransaction.getTo() == null || ccTransaction.getTo().isEmpty()) { if (ccTransaction.getTo() == null || ccTransaction.getTo().isEmpty()) {
@ -374,24 +375,37 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
//TODO check server connection //TODO check server connection
//TODO validate to address //TODO validate to address
System.out.println("GeneralAccount Manager Send request, asking fee");
InsightApiGenerator.getEstimateFee(this.cryptoCoin,new ApiRequest(1, new ApiRequestListener() { InsightApiGenerator.getEstimateFee(this.cryptoCoin,new ApiRequest(1, new ApiRequestListener() {
@Override @Override
public void success(Object answer, int idPetition) { public void success(Object answer, int idPetition) {
System.out.println("GeneralAccount Manager Send request, fee " + answer.toString());
try {
Transaction tx = new Transaction(cryptoCoin.getParameters()); Transaction tx = new Transaction(cryptoCoin.getParameters());
long currentAmount = 0; long currentAmount = 0;
long fee = -1; long fee = -1;
long feeRate = (long)(((double)answer) * Math.pow(10,cryptoCoin.getPrecision())); long feeRate = (long) (((double) answer) * Math.pow(10, cryptoCoin.getPrecision()));
fee = 226 * feeRate; fee = 226 * feeRate;
System.out.println("GeneralAccount Manager Send request getting utxos" );
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext()); CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
db.bitcoinTransactionDao(); db.bitcoinTransactionDao();
List<BitcoinTransactionGTxIO> utxos = getUtxos(request.getSourceAccount().getId(),db); List<BitcoinTransactionGTxIO> utxos = getUtxos(request.getSourceAccount().getId(), db);
System.out.println("GeneralAccount Manager Send request utxos found " + utxos.size() );
for(BitcoinTransactionGTxIO utxo : utxos){
currentAmount += utxo.getAmount();
if(currentAmount >= request.getAmount() + fee) {
break;
}
}
if(currentAmount< request.getAmount() + fee){ if (currentAmount < request.getAmount() + fee) {
System.out.println("GeneralAccount Manager Send request no balance" );
request.setStatus(BitcoinSendRequest.StatusCode.NO_BALANCE); request.setStatus(BitcoinSendRequest.StatusCode.NO_BALANCE);
return; return;
} }
AccountSeed seed = db.accountSeedDao().findById(request.getSourceAccount().getSeedId()); AccountSeed seed = db.accountSeedDao().findById(request.getSourceAccount().getSeedId());
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(), DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
new ChildNumber(44, true)); new ChildNumber(44, true));
@ -423,17 +437,17 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
//Change address //Change address
long remain = currentAmount - request.getAmount() - fee; long remain = currentAmount - request.getAmount() - fee;
if( remain > 0 ) { if (remain > 0) {
long index = db.bitcoinAddressDao().getLastChangeAddress(request.getSourceAccount().getId()); long index = db.bitcoinAddressDao().getLastChangeAddress(request.getSourceAccount().getId());
BitcoinAddress btAddress = db.bitcoinAddressDao().getChangeByIndex(index); BitcoinAddress btAddress = db.bitcoinAddressDao().getChangeByIndex(index);
Address changeAddr; Address changeAddr;
if(btAddress != null && db.bitcoinTransactionDao().getGtxIOByAddress(btAddress.getAddress()).size()<=0){ if (btAddress != null && db.bitcoinTransactionDao().getGtxIOByAddress(btAddress.getAddress()).size() <= 0) {
changeAddr = Address.fromBase58(cryptoCoin.getParameters(), btAddress.getAddress()); changeAddr = Address.fromBase58(cryptoCoin.getParameters(), btAddress.getAddress());
}else{ } else {
if(btAddress == null){ if (btAddress == null) {
index = 0; index = 0;
}else{ } else {
index++; index++;
} }
btAddress = new BitcoinAddress(); btAddress = new BitcoinAddress();
@ -447,36 +461,48 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
tx.addOutput(Coin.valueOf(remain), changeAddr); tx.addOutput(Coin.valueOf(remain), changeAddr);
} }
for(BitcoinTransactionGTxIO utxo: utxos) { for (BitcoinTransactionGTxIO utxo : utxos) {
Sha256Hash txHash = Sha256Hash.wrap(utxo.getOriginalTxId()); Sha256Hash txHash = Sha256Hash.wrap(utxo.getOriginalTxId());
Script script = new Script(Util.hexToBytes(utxo.getScriptHex())); Script script = new Script(Util.hexToBytes(utxo.getScriptHex()));
TransactionOutPoint outPoint = new TransactionOutPoint(cryptoCoin.getParameters(), utxo.getIndex(), txHash); TransactionOutPoint outPoint = new TransactionOutPoint(cryptoCoin.getParameters(), utxo.getIndex(), txHash);
BitcoinAddress btAddress = db.bitcoinAddressDao().getdadress(utxo.getAddress()); BitcoinAddress btAddress = db.bitcoinAddressDao().getdadress(utxo.getAddress());
ECKey addrKey; ECKey addrKey;
if(btAddress.isChange()){ if (btAddress.isChange()) {
addrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false)); addrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false));
}else{ } else {
addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) btAddress.getIndex(), true)); addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) btAddress.getIndex(), true));
} }
tx.addSignedInput(outPoint, script, addrKey, Transaction.SigHash.ALL, true); tx.addSignedInput(outPoint, script, addrKey, Transaction.SigHash.ALL, true);
currentAmount -= utxo.getAmount();
if(currentAmount<= 0){
break;
}
} }
InsightApiGenerator.broadcastTransaction(cryptoCoin,Util.bytesToHex(tx.bitcoinSerialize()),new ApiRequest(1, new ApiRequestListener() { System.out.println("GeneralAccount Manager Send request rawtx " +Util.bytesToHex(tx.bitcoinSerialize()) );
InsightApiGenerator.broadcastTransaction(cryptoCoin, Util.bytesToHex(tx.bitcoinSerialize()), new ApiRequest(1, new ApiRequestListener() {
@Override @Override
public void success(Object answer, int idPetition) { public void success(Object answer, int idPetition) {
System.out.println("GeneralAccount MAnager succed send");
request.setStatus(BitcoinSendRequest.StatusCode.SUCCEEDED); request.setStatus(BitcoinSendRequest.StatusCode.SUCCEEDED);
} }
@Override @Override
public void fail(int idPetition) { public void fail(int idPetition) {
System.out.println("GeneralAccount MAnager succed fail");
request.setStatus(BitcoinSendRequest.StatusCode.PETITION_FAILED); request.setStatus(BitcoinSendRequest.StatusCode.PETITION_FAILED);
} }
})); }));
}catch(Exception e){
System.out.println("GeneralAccount Manager Send request error ");
e.printStackTrace();
}
} }
@Override @Override
public void fail(int idPetition) { public void fail(int idPetition) {
System.out.println("GeneralAccount Manager Send request fee fail" );
request.setStatus(BitcoinSendRequest.StatusCode.NO_FEE); request.setStatus(BitcoinSendRequest.StatusCode.NO_FEE);
} }

View file

@ -89,7 +89,7 @@ public class BitcoinSendRequest extends CryptoNetInfoRequest {
public void setStatus(StatusCode code){ public void setStatus(StatusCode code){
this.status = code; this.status = code;
this._fireOnCarryOutEvent(); this.validate();
} }
public StatusCode getStatus() { public StatusCode getStatus() {