forked from Qortal/qortal
Bugfixes to online trade sigs + bridging from PRESENCE transactions
This commit is contained in:
parent
01d810fc00
commit
cb57af3c53
@ -338,9 +338,15 @@ public class TradeBot implements Listener {
|
|||||||
private void expireOldOnlineSignatures() {
|
private void expireOldOnlineSignatures() {
|
||||||
long now = NTP.getTime();
|
long now = NTP.getTime();
|
||||||
|
|
||||||
synchronized (this.pendingOnlineSignatures) {
|
int removedCount = 0;
|
||||||
this.pendingOnlineSignatures.removeIf(onlineTradeData -> onlineTradeData.getTimestamp() <= now);
|
synchronized (this.allOnlineByPubkey) {
|
||||||
|
int preRemoveCount = this.allOnlineByPubkey.size();
|
||||||
|
this.allOnlineByPubkey.values().removeIf(onlineTradeData -> onlineTradeData.getTimestamp() <= now);
|
||||||
|
removedCount = this.allOnlineByPubkey.size() - preRemoveCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (removedCount > 0)
|
||||||
|
LOGGER.trace("Removed {} old online trade signatures", removedCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*package*/ void updatePresence(Repository repository, TradeBotData tradeBotData, CrossChainTradeData tradeData)
|
/*package*/ void updatePresence(Repository repository, TradeBotData tradeBotData, CrossChainTradeData tradeData)
|
||||||
@ -359,28 +365,33 @@ public class TradeBot implements Listener {
|
|||||||
|
|
||||||
long now = NTP.getTime();
|
long now = NTP.getTime();
|
||||||
|
|
||||||
// Timestamps are considered good for full lifetime...
|
// Timestamps are considered good for full lifetime, but we'll refresh if older than half-lifetime
|
||||||
long expiry = (now + ONLINE_LIFETIME) % ONLINE_LIFETIME;
|
long threshold = (now / (ONLINE_LIFETIME / 2)) * (ONLINE_LIFETIME / 2);
|
||||||
// ... but refresh if older than half-lifetime
|
long newExpiry = threshold + ONLINE_LIFETIME / 2;
|
||||||
long threshold = (now + ONLINE_LIFETIME / 2) % (ONLINE_LIFETIME / 2);
|
|
||||||
|
|
||||||
ByteArray pubkeyByteArray = ByteArray.of(tradeNativeAccount.getPublicKey());
|
ByteArray pubkeyByteArray = ByteArray.of(tradeNativeAccount.getPublicKey());
|
||||||
// If map's timestamp is missing, or too old, use the new timestamp - otherwise use existing timestamp.
|
// If map's timestamp is missing, or too old, use the new timestamp - otherwise use existing timestamp.
|
||||||
long timestamp = ourTimestampsByPubkey.compute(pubkeyByteArray, (k, v) -> (v == null || v <= threshold) ? expiry : v);
|
synchronized (this.ourTimestampsByPubkey) {
|
||||||
|
Long currentTimestamp = this.ourTimestampsByPubkey.get(pubkeyByteArray);
|
||||||
|
|
||||||
// If timestamp hasn't been updated then nothing to do
|
if (currentTimestamp != null && currentTimestamp > threshold)
|
||||||
if (timestamp != expiry)
|
// timestamp still good
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
this.ourTimestampsByPubkey.put(pubkeyByteArray, newExpiry);
|
||||||
|
}
|
||||||
|
|
||||||
// Create signature
|
// Create signature
|
||||||
byte[] signature = tradeNativeAccount.sign(Longs.toByteArray(timestamp));
|
byte[] signature = tradeNativeAccount.sign(Longs.toByteArray(newExpiry));
|
||||||
|
|
||||||
// Add new online info to queue to be broadcast around network
|
// Add new online info to queue to be broadcast around network
|
||||||
OnlineTradeData onlineTradeData = new OnlineTradeData(timestamp, tradeNativeAccount.getPublicKey(), signature, atAddress);
|
OnlineTradeData onlineTradeData = new OnlineTradeData(newExpiry, tradeNativeAccount.getPublicKey(), signature, atAddress);
|
||||||
this.pendingOnlineSignatures.add(onlineTradeData);
|
this.pendingOnlineSignatures.add(onlineTradeData);
|
||||||
|
|
||||||
this.allOnlineByPubkey.put(pubkeyByteArray, onlineTradeData);
|
this.allOnlineByPubkey.put(pubkeyByteArray, onlineTradeData);
|
||||||
rebuildSafeAllOnline();
|
rebuildSafeAllOnline();
|
||||||
|
|
||||||
|
LOGGER.trace("New signed timestamp {} for our online trade {}", newExpiry, atAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rebuildSafeAllOnline() {
|
private void rebuildSafeAllOnline() {
|
||||||
@ -400,6 +411,8 @@ public class TradeBot implements Listener {
|
|||||||
this.pendingOnlineSignatures.clear();
|
this.pendingOnlineSignatures.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.trace("Broadcasting {} new online trades", safeOnlineSignatures.size());
|
||||||
|
|
||||||
OnlineTradesMessage onlineTradesMessage = new OnlineTradesMessage(safeOnlineSignatures);
|
OnlineTradesMessage onlineTradesMessage = new OnlineTradesMessage(safeOnlineSignatures);
|
||||||
Network.getInstance().broadcast(peer -> onlineTradesMessage);
|
Network.getInstance().broadcast(peer -> onlineTradesMessage);
|
||||||
|
|
||||||
@ -415,6 +428,13 @@ public class TradeBot implements Listener {
|
|||||||
|
|
||||||
List<OnlineTradeData> safeOnlineSignatures = List.copyOf(this.safeAllOnlineByPubkey.values());
|
List<OnlineTradeData> safeOnlineSignatures = List.copyOf(this.safeAllOnlineByPubkey.values());
|
||||||
|
|
||||||
|
if (safeOnlineSignatures.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
LOGGER.trace("Broadcasting all {} known online trades. Next broadcast timestamp: {}",
|
||||||
|
safeOnlineSignatures.size(), nextBroadcastTimestamp
|
||||||
|
);
|
||||||
|
|
||||||
GetOnlineTradesMessage getOnlineTradesMessage = new GetOnlineTradesMessage(safeOnlineSignatures);
|
GetOnlineTradesMessage getOnlineTradesMessage = new GetOnlineTradesMessage(safeOnlineSignatures);
|
||||||
Network.getInstance().broadcast(peer -> getOnlineTradesMessage);
|
Network.getInstance().broadcast(peer -> getOnlineTradesMessage);
|
||||||
}
|
}
|
||||||
@ -427,6 +447,8 @@ public class TradeBot implements Listener {
|
|||||||
List<OnlineTradeData> peersOnlineTrades = getOnlineTradesMessage.getOnlineTrades();
|
List<OnlineTradeData> peersOnlineTrades = getOnlineTradesMessage.getOnlineTrades();
|
||||||
|
|
||||||
Map<ByteArray, OnlineTradeData> entriesUnknownToPeer = new HashMap<>(this.safeAllOnlineByPubkey);
|
Map<ByteArray, OnlineTradeData> entriesUnknownToPeer = new HashMap<>(this.safeAllOnlineByPubkey);
|
||||||
|
int knownCount = entriesUnknownToPeer.size();
|
||||||
|
|
||||||
for (OnlineTradeData peersOnlineTrade : peersOnlineTrades) {
|
for (OnlineTradeData peersOnlineTrade : peersOnlineTrades) {
|
||||||
ByteArray pubkeyByteArray = ByteArray.of(peersOnlineTrade.getPublicKey());
|
ByteArray pubkeyByteArray = ByteArray.of(peersOnlineTrade.getPublicKey());
|
||||||
|
|
||||||
@ -436,6 +458,10 @@ public class TradeBot implements Listener {
|
|||||||
entriesUnknownToPeer.remove(pubkeyByteArray);
|
entriesUnknownToPeer.remove(pubkeyByteArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGGER.trace("Sending {} known \\ {} peers = {} online trades to peer {}",
|
||||||
|
knownCount, peersOnlineTrades.size(), entriesUnknownToPeer.size()
|
||||||
|
);
|
||||||
|
|
||||||
// Send complement to peer
|
// Send complement to peer
|
||||||
List<OnlineTradeData> safeOnlineSignatures = List.copyOf(entriesUnknownToPeer.values());
|
List<OnlineTradeData> safeOnlineSignatures = List.copyOf(entriesUnknownToPeer.values());
|
||||||
Message responseMessage = new OnlineTradesMessage(safeOnlineSignatures);
|
Message responseMessage = new OnlineTradesMessage(safeOnlineSignatures);
|
||||||
@ -452,7 +478,7 @@ public class TradeBot implements Listener {
|
|||||||
|
|
||||||
long now = NTP.getTime();
|
long now = NTP.getTime();
|
||||||
// Timestamps after this are too far into the future
|
// Timestamps after this are too far into the future
|
||||||
long futureThreshold = (now % ONLINE_LIFETIME) + ONLINE_LIFETIME + ONLINE_LIFETIME / 2;
|
long futureThreshold = (now / ONLINE_LIFETIME + 1) * ONLINE_LIFETIME;
|
||||||
// Timestamps before this are too far into the past
|
// Timestamps before this are too far into the past
|
||||||
long pastThreshold = now;
|
long pastThreshold = now;
|
||||||
|
|
||||||
@ -464,46 +490,101 @@ public class TradeBot implements Listener {
|
|||||||
for (OnlineTradeData peersOnlineTrade : peersOnlineTrades) {
|
for (OnlineTradeData peersOnlineTrade : peersOnlineTrades) {
|
||||||
long timestamp = peersOnlineTrade.getTimestamp();
|
long timestamp = peersOnlineTrade.getTimestamp();
|
||||||
|
|
||||||
if (timestamp < pastThreshold || timestamp > futureThreshold)
|
// Ignore if timestamp is out of bounds
|
||||||
|
if (timestamp < pastThreshold || timestamp > futureThreshold) {
|
||||||
|
if (timestamp < pastThreshold)
|
||||||
|
LOGGER.trace("Ignoring online trade {} from peer {} as timestamp {} is too old vs {}",
|
||||||
|
peersOnlineTrade.getAtAddress(), peer, timestamp, pastThreshold
|
||||||
|
);
|
||||||
|
else
|
||||||
|
LOGGER.trace("Ignoring online trade {} from peer {} as timestamp {} is too new vs {}",
|
||||||
|
peersOnlineTrade.getAtAddress(), peer, timestamp, pastThreshold
|
||||||
|
);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ByteArray pubkeyByteArray = ByteArray.of(peersOnlineTrade.getPublicKey());
|
ByteArray pubkeyByteArray = ByteArray.of(peersOnlineTrade.getPublicKey());
|
||||||
|
|
||||||
// Ignore if we've previously verified this timestamp+publickey combo
|
// Ignore if we've previously verified this timestamp+publickey combo or sent timestamp is older
|
||||||
OnlineTradeData existingTradeData = this.safeAllOnlineByPubkey.get(pubkeyByteArray);
|
OnlineTradeData existingTradeData = this.safeAllOnlineByPubkey.get(pubkeyByteArray);
|
||||||
if (existingTradeData != null && existingTradeData.getTimestamp() == timestamp)
|
if (existingTradeData != null && timestamp <= existingTradeData.getTimestamp()) {
|
||||||
|
if (timestamp == existingTradeData.getTimestamp())
|
||||||
|
LOGGER.trace("Ignoring online trade {} from peer {} as we have verified timestamp {} before",
|
||||||
|
peersOnlineTrade.getAtAddress(), peer, timestamp
|
||||||
|
);
|
||||||
|
else
|
||||||
|
LOGGER.trace("Ignoring online trade {} from peer {} as timestamp {} is older than latest {}",
|
||||||
|
peersOnlineTrade.getAtAddress(), peer, timestamp, existingTradeData.getTimestamp()
|
||||||
|
);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Check timestamp signature
|
// Check timestamp signature
|
||||||
byte[] timestampSignature = peersOnlineTrade.getSignature();
|
byte[] timestampSignature = peersOnlineTrade.getSignature();
|
||||||
byte[] timestampBytes = Longs.toByteArray(timestamp);
|
byte[] timestampBytes = Longs.toByteArray(timestamp);
|
||||||
byte[] publicKey = peersOnlineTrade.getPublicKey();
|
byte[] publicKey = peersOnlineTrade.getPublicKey();
|
||||||
if (!Crypto.verify(publicKey, timestampSignature, timestampBytes))
|
if (!Crypto.verify(publicKey, timestampSignature, timestampBytes)) {
|
||||||
|
LOGGER.trace("Ignoring online trade {} from peer {} as signature failed to verify",
|
||||||
|
peersOnlineTrade.getAtAddress(), peer
|
||||||
|
);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ATData atData = repository.getATRepository().fromATAddress(peersOnlineTrade.getAtAddress());
|
ATData atData = repository.getATRepository().fromATAddress(peersOnlineTrade.getAtAddress());
|
||||||
if (atData == null || atData.getIsFrozen() || atData.getIsFinished())
|
if (atData == null || atData.getIsFrozen() || atData.getIsFinished()) {
|
||||||
|
if (atData == null)
|
||||||
|
LOGGER.trace("Ignoring online trade {} from peer {} as AT doesn't exist",
|
||||||
|
peersOnlineTrade.getAtAddress(), peer
|
||||||
|
);
|
||||||
|
else
|
||||||
|
LOGGER.trace("Ignoring online trade {} from peer {} as AT is frozen or finished",
|
||||||
|
peersOnlineTrade.getAtAddress(), peer
|
||||||
|
);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ByteArray atCodeHash = new ByteArray(atData.getCodeHash());
|
ByteArray atCodeHash = new ByteArray(atData.getCodeHash());
|
||||||
Supplier<ACCT> acctSupplier = acctSuppliersByCodeHash.get(atCodeHash);
|
Supplier<ACCT> acctSupplier = acctSuppliersByCodeHash.get(atCodeHash);
|
||||||
if (acctSupplier == null)
|
if (acctSupplier == null) {
|
||||||
|
LOGGER.trace("Ignoring online trade {} from peer {} as AT isn't a known ACCT?",
|
||||||
|
peersOnlineTrade.getAtAddress(), peer
|
||||||
|
);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
CrossChainTradeData tradeData = acctSupplier.get().populateTradeData(repository, atData);
|
CrossChainTradeData tradeData = acctSupplier.get().populateTradeData(repository, atData);
|
||||||
if (tradeData == null)
|
if (tradeData == null) {
|
||||||
|
LOGGER.trace("Ignoring online trade {} from peer {} as trade data not found?",
|
||||||
|
peersOnlineTrade.getAtAddress(), peer
|
||||||
|
);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Convert signer's public key to address form
|
// Convert signer's public key to address form
|
||||||
String signerAddress = Crypto.toAddress(publicKey);
|
String signerAddress = Crypto.toAddress(publicKey);
|
||||||
|
|
||||||
// Signer's public key (in address form) must match Bob's / Alice's trade public key (in address form)
|
// Signer's public key (in address form) must match Bob's / Alice's trade public key (in address form)
|
||||||
if (!signerAddress.equals(tradeData.qortalCreatorTradeAddress) && !signerAddress.equals(tradeData.qortalPartnerAddress))
|
if (!signerAddress.equals(tradeData.qortalCreatorTradeAddress) && !signerAddress.equals(tradeData.qortalPartnerAddress)) {
|
||||||
|
LOGGER.trace("Ignoring online trade {} from peer {} as signer isn't Alice or Bob?",
|
||||||
|
peersOnlineTrade.getAtAddress(), peer
|
||||||
|
);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// This is new to us
|
// This is new to us
|
||||||
this.allOnlineByPubkey.put(pubkeyByteArray, peersOnlineTrade);
|
this.allOnlineByPubkey.put(pubkeyByteArray, peersOnlineTrade);
|
||||||
++newCount;
|
++newCount;
|
||||||
|
|
||||||
|
LOGGER.trace("Added online trade {} from peer {} with timestamp {}",
|
||||||
|
peersOnlineTrade.getAtAddress(), peer, timestamp
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
LOGGER.error("Couldn't process ONLINE_TRADES message due to repository issue", e);
|
LOGGER.error("Couldn't process ONLINE_TRADES message due to repository issue", e);
|
||||||
@ -514,4 +595,18 @@ public class TradeBot implements Listener {
|
|||||||
rebuildSafeAllOnline();
|
rebuildSafeAllOnline();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void bridgePresence(long timestamp, byte[] publicKey, byte[] signature, String atAddress) {
|
||||||
|
long expiry = (timestamp / ONLINE_LIFETIME + 1) * ONLINE_LIFETIME;
|
||||||
|
ByteArray pubkeyByteArray = ByteArray.of(publicKey);
|
||||||
|
|
||||||
|
OnlineTradeData fakeOnlineTradeData = new OnlineTradeData(expiry, publicKey, signature, atAddress);
|
||||||
|
|
||||||
|
OnlineTradeData computedOnlineTradeData = this.allOnlineByPubkey.compute(pubkeyByteArray, (k, v) -> (v == null || v.getTimestamp() < expiry) ? fakeOnlineTradeData : v);
|
||||||
|
|
||||||
|
if (computedOnlineTradeData == fakeOnlineTradeData) {
|
||||||
|
LOGGER.trace("Bridged online trade {} with timestamp {}", atAddress, expiry);
|
||||||
|
rebuildSafeAllOnline();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,11 @@ public class OnlineTradeData {
|
|||||||
protected OnlineTradeData() {
|
protected OnlineTradeData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public OnlineTradeData(long timestamp, byte[] publicKey, byte[] signature, String address) {
|
public OnlineTradeData(long timestamp, byte[] publicKey, byte[] signature, String atAddress) {
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
this.publicKey = publicKey;
|
this.publicKey = publicKey;
|
||||||
this.signature = signature;
|
this.signature = signature;
|
||||||
this.atAddress = address;
|
this.atAddress = atAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OnlineTradeData(long timestamp, byte[] publicKey) {
|
public OnlineTradeData(long timestamp, byte[] publicKey) {
|
||||||
|
@ -95,8 +95,9 @@ public abstract class Message {
|
|||||||
|
|
||||||
ARBITRARY_SIGNATURES(130),
|
ARBITRARY_SIGNATURES(130),
|
||||||
|
|
||||||
GET_ONLINE_TRADES(140),
|
ONLINE_TRADES(140),
|
||||||
ONLINE_TRADES(141);
|
GET_ONLINE_TRADES(141),
|
||||||
|
;
|
||||||
|
|
||||||
public final int value;
|
public final int value;
|
||||||
public final Method fromByteBufferMethod;
|
public final Method fromByteBufferMethod;
|
||||||
|
@ -4,6 +4,7 @@ import com.google.common.primitives.Ints;
|
|||||||
import com.google.common.primitives.Longs;
|
import com.google.common.primitives.Longs;
|
||||||
import org.qortal.data.network.OnlineTradeData;
|
import org.qortal.data.network.OnlineTradeData;
|
||||||
import org.qortal.transform.Transformer;
|
import org.qortal.transform.Transformer;
|
||||||
|
import org.qortal.utils.Base58;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -53,11 +54,11 @@ public class OnlineTradesMessage extends Message {
|
|||||||
byte[] signature = new byte[Transformer.SIGNATURE_LENGTH];
|
byte[] signature = new byte[Transformer.SIGNATURE_LENGTH];
|
||||||
bytes.get(signature);
|
bytes.get(signature);
|
||||||
|
|
||||||
byte[] addressBytes = new byte[Transformer.ADDRESS_LENGTH];
|
byte[] atAddressBytes = new byte[Transformer.ADDRESS_LENGTH];
|
||||||
bytes.get(addressBytes);
|
bytes.get(atAddressBytes);
|
||||||
String address = new String(addressBytes, StandardCharsets.UTF_8);
|
String atAddress = Base58.encode(atAddressBytes);
|
||||||
|
|
||||||
onlineTrades.add(new OnlineTradeData(timestamp, publicKey, signature, address));
|
onlineTrades.add(new OnlineTradeData(timestamp, publicKey, signature, atAddress));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes.hasRemaining()) {
|
if (bytes.hasRemaining()) {
|
||||||
@ -108,7 +109,7 @@ public class OnlineTradesMessage extends Message {
|
|||||||
|
|
||||||
bytes.write(onlineTradeData.getSignature());
|
bytes.write(onlineTradeData.getSignature());
|
||||||
|
|
||||||
bytes.write(onlineTradeData.getAtAddress().getBytes(StandardCharsets.UTF_8));
|
bytes.write(Base58.decode(onlineTradeData.getAtAddress()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.qortal.account.Account;
|
import org.qortal.account.Account;
|
||||||
import org.qortal.controller.Controller;
|
import org.qortal.controller.Controller;
|
||||||
|
import org.qortal.controller.tradebot.TradeBot;
|
||||||
import org.qortal.crosschain.ACCT;
|
import org.qortal.crosschain.ACCT;
|
||||||
import org.qortal.crosschain.SupportedBlockchain;
|
import org.qortal.crosschain.SupportedBlockchain;
|
||||||
import org.qortal.crypto.Crypto;
|
import org.qortal.crypto.Crypto;
|
||||||
@ -191,12 +192,16 @@ public class PresenceTransaction extends Transaction {
|
|||||||
CrossChainTradeData crossChainTradeData = acctSupplier.get().populateTradeData(repository, atData);
|
CrossChainTradeData crossChainTradeData = acctSupplier.get().populateTradeData(repository, atData);
|
||||||
|
|
||||||
// OK if signer's public key (in address form) matches Bob's trade public key (in address form)
|
// OK if signer's public key (in address form) matches Bob's trade public key (in address form)
|
||||||
if (signerAddress.equals(crossChainTradeData.qortalCreatorTradeAddress))
|
if (signerAddress.equals(crossChainTradeData.qortalCreatorTradeAddress)) {
|
||||||
|
TradeBot.getInstance().bridgePresence(this.presenceTransactionData.getTimestamp(), this.transactionData.getCreatorPublicKey(), timestampSignature, atData.getATAddress());
|
||||||
return ValidationResult.OK;
|
return ValidationResult.OK;
|
||||||
|
}
|
||||||
|
|
||||||
// OK if signer's public key (in address form) matches Alice's trade public key (in address form)
|
// OK if signer's public key (in address form) matches Alice's trade public key (in address form)
|
||||||
if (signerAddress.equals(crossChainTradeData.qortalPartnerAddress))
|
if (signerAddress.equals(crossChainTradeData.qortalPartnerAddress)) {
|
||||||
|
TradeBot.getInstance().bridgePresence(this.presenceTransactionData.getTimestamp(), this.transactionData.getCreatorPublicKey(), timestampSignature, atData.getATAddress());
|
||||||
return ValidationResult.OK;
|
return ValidationResult.OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ValidationResult.AT_UNKNOWN;
|
return ValidationResult.AT_UNKNOWN;
|
||||||
|
Loading…
Reference in New Issue
Block a user