Improve /crosschain/tradebot/respond with varied API errors such as BTC_BALANCE_ISSUE, BTC_NETWORK_ISSUE, etc. instead of just "false"

This commit is contained in:
catbref 2020-08-05 10:05:09 +01:00
parent 36d0abe635
commit ec2c9d2a44
2 changed files with 27 additions and 7 deletions

View File

@ -1045,7 +1045,7 @@ public class CrossChainResource {
)
}
)
@ApiErrors({ApiError.INVALID_PUBLIC_KEY, ApiError.INVALID_ADDRESS, ApiError.REPOSITORY_ISSUE})
@ApiErrors({ApiError.INVALID_PUBLIC_KEY, ApiError.INVALID_ADDRESS, ApiError.INVALID_CRITERIA, ApiError.BTC_BALANCE_ISSUE, ApiError.BTC_NETWORK_ISSUE, ApiError.REPOSITORY_ISSUE})
public String tradeBotResponder(TradeBotRespondRequest tradeBotRespondRequest) {
Security.checkApiCallAllowed(request);
@ -1068,9 +1068,22 @@ public class CrossChainResource {
if (crossChainTradeData.mode != BTCACCT.Mode.OFFERING)
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA);
boolean result = TradeBot.startResponse(repository, crossChainTradeData, tradeBotRespondRequest.xprv58, tradeBotRespondRequest.receivingAddress);
TradeBot.ResponseResult result = TradeBot.startResponse(repository, crossChainTradeData, tradeBotRespondRequest.xprv58, tradeBotRespondRequest.receivingAddress);
return result ? "true" : "false";
switch (result) {
case OK:
return "true";
case INSUFFICIENT_FUNDS:
case BTC_BALANCE_ISSUE:
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BTC_BALANCE_ISSUE);
case BTC_NETWORK_ISSUE:
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.BTC_NETWORK_ISSUE);
default:
return "false";
}
} catch (DataException e) {
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
}

View File

@ -45,6 +45,8 @@ import org.qortal.utils.NTP;
public class TradeBot {
public enum ResponseResult { OK, INSUFFICIENT_FUNDS, BTC_BALANCE_ISSUE, BTC_NETWORK_ISSUE }
private static final Logger LOGGER = LogManager.getLogger(TradeBot.class);
private static final Random RANDOM = new SecureRandom();
private static final long FEE_AMOUNT = 1000L;
@ -203,7 +205,7 @@ public class TradeBot {
* @return true if P2SH-A funding transaction successfully broadcast to Bitcoin network, false otherwise
* @throws DataException
*/
public static boolean startResponse(Repository repository, CrossChainTradeData crossChainTradeData, String xprv58, String receivingAddress) throws DataException {
public static ResponseResult startResponse(Repository repository, CrossChainTradeData crossChainTradeData, String xprv58, String receivingAddress) throws DataException {
byte[] tradePrivateKey = generateTradePrivateKey();
byte[] secretA = generateSecret();
byte[] hashOfSecretA = Crypto.hash160(secretA);
@ -233,7 +235,7 @@ public class TradeBot {
Transaction fundingCheckTransaction = BTC.getInstance().buildSpend(xprv58, tradeForeignAddress, totalFundsRequired);
if (fundingCheckTransaction == null)
return false;
return ResponseResult.INSUFFICIENT_FUNDS;
// P2SH-A to be funded
byte[] redeemScriptBytes = BTCP2SH.buildScript(tradeForeignPublicKeyHash, lockTimeA, crossChainTradeData.creatorBitcoinPKH, hashOfSecretA);
@ -241,10 +243,15 @@ public class TradeBot {
// Fund P2SH-A
Transaction p2shFundingTransaction = BTC.getInstance().buildSpend(tradeBotData.getXprv58(), p2shAddress, crossChainTradeData.expectedBitcoin + FEE_AMOUNT);
if (p2shFundingTransaction == null) {
LOGGER.warn(() -> String.format("Unable to build P2SH-A funding transaction - lack of funds?"));
return ResponseResult.BTC_BALANCE_ISSUE;
}
if (!BTC.getInstance().broadcastTransaction(p2shFundingTransaction)) {
// We couldn't fund P2SH-A at this time
LOGGER.debug(() -> String.format("Couldn't broadcast P2SH-A funding transaction?"));
return false;
return ResponseResult.BTC_NETWORK_ISSUE;
}
repository.getCrossChainRepository().save(tradeBotData);
@ -252,7 +259,7 @@ public class TradeBot {
LOGGER.info(() -> String.format("Funding P2SH-A %s. Waiting for confirmation", p2shAddress));
return true;
return ResponseResult.OK;
}
private static byte[] generateTradePrivateKey() {