forked from Qortal/qortal
Update BTC-ACCT 'cancel' API call to expect AT creator's as sender
This commit is contained in:
parent
23a524b464
commit
8f2985862d
@ -8,8 +8,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
@XmlAccessorType(XmlAccessType.FIELD)
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
public class CrossChainCancelRequest {
|
public class CrossChainCancelRequest {
|
||||||
|
|
||||||
@Schema(description = "AT creator's 'trade' public key", example = "K6wuddsBV3HzRrXFFezE7P5MoRXp5m3mEDokRDGZB6ry")
|
@Schema(description = "AT creator's public key", example = "K6wuddsBV3HzRrXFFezE7P5MoRXp5m3mEDokRDGZB6ry")
|
||||||
public byte[] tradePublicKey;
|
public byte[] creatorPublicKey;
|
||||||
|
|
||||||
@Schema(description = "Qortal trade AT address")
|
@Schema(description = "Qortal trade AT address")
|
||||||
public String atAddress;
|
public String atAddress;
|
||||||
|
@ -380,7 +380,7 @@ public class CrossChainResource {
|
|||||||
summary = "Builds raw, unsigned 'cancel' MESSAGE transaction that cancels cross-chain trade offer",
|
summary = "Builds raw, unsigned 'cancel' MESSAGE transaction that cancels cross-chain trade offer",
|
||||||
description = "Specify address of cross-chain AT that needs to be cancelled.<br>"
|
description = "Specify address of cross-chain AT that needs to be cancelled.<br>"
|
||||||
+ "AT needs to be in 'offer' mode. Messages sent to an AT in 'trade' mode will be ignored, but still cost fees to send!<br>"
|
+ "AT needs to be in 'offer' mode. Messages sent to an AT in 'trade' mode will be ignored, but still cost fees to send!<br>"
|
||||||
+ "You need to sign output with trade's private key otherwise the MESSAGE transaction will be invalid.",
|
+ "You need to sign output with AT creator's private key otherwise the MESSAGE transaction will be invalid.",
|
||||||
requestBody = @RequestBody(
|
requestBody = @RequestBody(
|
||||||
required = true,
|
required = true,
|
||||||
content = @Content(
|
content = @Content(
|
||||||
@ -404,9 +404,9 @@ public class CrossChainResource {
|
|||||||
public String buildCancelMessage(CrossChainCancelRequest cancelRequest) {
|
public String buildCancelMessage(CrossChainCancelRequest cancelRequest) {
|
||||||
Security.checkApiCallAllowed(request);
|
Security.checkApiCallAllowed(request);
|
||||||
|
|
||||||
byte[] tradePublicKey = cancelRequest.tradePublicKey;
|
byte[] creatorPublicKey = cancelRequest.creatorPublicKey;
|
||||||
|
|
||||||
if (tradePublicKey == null || tradePublicKey.length != Transformer.PUBLIC_KEY_LENGTH)
|
if (creatorPublicKey == null || creatorPublicKey.length != Transformer.PUBLIC_KEY_LENGTH)
|
||||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_PUBLIC_KEY);
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_PUBLIC_KEY);
|
||||||
|
|
||||||
if (cancelRequest.atAddress == null || !Crypto.isValidAtAddress(cancelRequest.atAddress))
|
if (cancelRequest.atAddress == null || !Crypto.isValidAtAddress(cancelRequest.atAddress))
|
||||||
@ -419,16 +419,16 @@ public class CrossChainResource {
|
|||||||
if (crossChainTradeData.mode != BTCACCT.Mode.OFFERING)
|
if (crossChainTradeData.mode != BTCACCT.Mode.OFFERING)
|
||||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA);
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA);
|
||||||
|
|
||||||
// Does supplied public key match trade public key?
|
// Does supplied public key match AT creator's public key?
|
||||||
if (!Crypto.toAddress(tradePublicKey).equals(crossChainTradeData.qortalCreatorTradeAddress))
|
if (!Arrays.equals(creatorPublicKey, atData.getCreatorPublicKey()))
|
||||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_PUBLIC_KEY);
|
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_PUBLIC_KEY);
|
||||||
|
|
||||||
// Good to make MESSAGE
|
// Good to make MESSAGE
|
||||||
|
|
||||||
String atCreatorAddress = crossChainTradeData.qortalCreator;
|
String atCreatorAddress = Crypto.toAddress(creatorPublicKey);
|
||||||
byte[] messageData = BTCACCT.buildCancelMessage(atCreatorAddress);
|
byte[] messageData = BTCACCT.buildCancelMessage(atCreatorAddress);
|
||||||
|
|
||||||
byte[] messageTransactionBytes = buildAtMessage(repository, tradePublicKey, cancelRequest.atAddress, messageData);
|
byte[] messageTransactionBytes = buildAtMessage(repository, creatorPublicKey, cancelRequest.atAddress, messageData);
|
||||||
|
|
||||||
return Base58.encode(messageTransactionBytes);
|
return Base58.encode(messageTransactionBytes);
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
@ -1222,12 +1222,18 @@ public class CrossChainResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private byte[] buildAtMessage(Repository repository, byte[] senderPublicKey, String atAddress, byte[] messageData) throws DataException {
|
private byte[] buildAtMessage(Repository repository, byte[] senderPublicKey, String atAddress, byte[] messageData) throws DataException {
|
||||||
// senderPublicKey is actually ephemeral trade public key, so there is no corresponding account and hence no reference
|
|
||||||
long txTimestamp = NTP.getTime();
|
long txTimestamp = NTP.getTime();
|
||||||
|
|
||||||
Random random = new Random();
|
// senderPublicKey could be ephemeral trade public key where there is no corresponding account and hence no reference
|
||||||
byte[] lastReference = new byte[Transformer.SIGNATURE_LENGTH];
|
String senderAddress = Crypto.toAddress(senderPublicKey);
|
||||||
random.nextBytes(lastReference);
|
byte[] lastReference = repository.getAccountRepository().getLastReference(senderAddress);
|
||||||
|
final boolean requiresPoW = lastReference == null;
|
||||||
|
|
||||||
|
if (requiresPoW) {
|
||||||
|
Random random = new Random();
|
||||||
|
lastReference = new byte[Transformer.SIGNATURE_LENGTH];
|
||||||
|
random.nextBytes(lastReference);
|
||||||
|
}
|
||||||
|
|
||||||
int version = 4;
|
int version = 4;
|
||||||
int nonce = 0;
|
int nonce = 0;
|
||||||
@ -1240,7 +1246,12 @@ public class CrossChainResource {
|
|||||||
|
|
||||||
MessageTransaction messageTransaction = new MessageTransaction(repository, messageTransactionData);
|
MessageTransaction messageTransaction = new MessageTransaction(repository, messageTransactionData);
|
||||||
|
|
||||||
messageTransaction.computeNonce();
|
if (requiresPoW) {
|
||||||
|
messageTransaction.computeNonce();
|
||||||
|
} else {
|
||||||
|
fee = messageTransaction.calcRecommendedFee();
|
||||||
|
messageTransactionData.setFee(fee);
|
||||||
|
}
|
||||||
|
|
||||||
ValidationResult result = messageTransaction.isValidUnconfirmed();
|
ValidationResult result = messageTransaction.isValidUnconfirmed();
|
||||||
if (result != ValidationResult.OK)
|
if (result != ValidationResult.OK)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user