forked from Qortal/qortal
WIP: PRESENCE transactions - support only TRADE_BOT type and restrict to known trades
This commit is contained in:
parent
15d25649b2
commit
a52c089728
@ -6,10 +6,14 @@ import java.util.List;
|
|||||||
import org.apache.logging.log4j.LogManager;
|
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.crosschain.BTCACCT;
|
||||||
import org.qortal.crypto.Crypto;
|
import org.qortal.crypto.Crypto;
|
||||||
import org.qortal.crypto.MemoryPoW;
|
import org.qortal.crypto.MemoryPoW;
|
||||||
|
import org.qortal.data.at.ATData;
|
||||||
|
import org.qortal.data.crosschain.CrossChainTradeData;
|
||||||
import org.qortal.data.transaction.PresenceTransactionData;
|
import org.qortal.data.transaction.PresenceTransactionData;
|
||||||
import org.qortal.data.transaction.TransactionData;
|
import org.qortal.data.transaction.TransactionData;
|
||||||
|
import org.qortal.data.transaction.PresenceTransactionData.PresenceType;
|
||||||
import org.qortal.group.Group;
|
import org.qortal.group.Group;
|
||||||
import org.qortal.repository.DataException;
|
import org.qortal.repository.DataException;
|
||||||
import org.qortal.repository.Repository;
|
import org.qortal.repository.Repository;
|
||||||
@ -104,15 +108,34 @@ public class PresenceTransaction extends Transaction {
|
|||||||
if (this.repository.getTransactionRepository().exists(this.presenceTransactionData.getSignature()))
|
if (this.repository.getTransactionRepository().exists(this.presenceTransactionData.getSignature()))
|
||||||
return ValidationResult.INVALID_BUT_OK;
|
return ValidationResult.INVALID_BUT_OK;
|
||||||
|
|
||||||
|
// We only support TRADE_BOT-type PRESENCE at this time
|
||||||
|
if (PresenceType.TRADE_BOT != this.presenceTransactionData.getPresenceType())
|
||||||
|
return ValidationResult.NOT_YET_RELEASED;
|
||||||
|
|
||||||
// Check timestamp signature
|
// Check timestamp signature
|
||||||
byte[] timestampSignature = this.presenceTransactionData.getTimestampSignature();
|
byte[] timestampSignature = this.presenceTransactionData.getTimestampSignature();
|
||||||
byte[] timestampBytes = Longs.toByteArray(this.presenceTransactionData.getTimestamp());
|
byte[] timestampBytes = Longs.toByteArray(this.presenceTransactionData.getTimestamp());
|
||||||
if (!Crypto.verify(this.transactionData.getCreatorPublicKey(), timestampSignature, timestampBytes))
|
if (!Crypto.verify(this.transactionData.getCreatorPublicKey(), timestampSignature, timestampBytes))
|
||||||
return ValidationResult.INVALID_TIMESTAMP_SIGNATURE;
|
return ValidationResult.INVALID_TIMESTAMP_SIGNATURE;
|
||||||
|
|
||||||
|
// Check signer is known trade address
|
||||||
|
String signerAddress = Crypto.toAddress(this.transactionData.getCreatorPublicKey());
|
||||||
|
|
||||||
|
byte[] codeHash = BTCACCT.CODE_BYTES_HASH;
|
||||||
|
boolean isExecutable = true;
|
||||||
|
|
||||||
|
List<ATData> atsData = repository.getATRepository().getATsByFunctionality(codeHash, isExecutable, null, null, null);
|
||||||
|
|
||||||
|
for (ATData atData : atsData) {
|
||||||
|
CrossChainTradeData crossChainTradeData = BTCACCT.populateTradeData(repository, atData);
|
||||||
|
|
||||||
|
if (crossChainTradeData.qortalCreatorTradeAddress.equals(signerAddress))
|
||||||
return ValidationResult.OK;
|
return ValidationResult.OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ValidationResult.AT_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSignatureValid() {
|
public boolean isSignatureValid() {
|
||||||
byte[] signature = this.transactionData.getSignature();
|
byte[] signature = this.transactionData.getSignature();
|
||||||
|
@ -4,18 +4,25 @@ import org.junit.After;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.qortal.account.PrivateKeyAccount;
|
import org.qortal.account.PrivateKeyAccount;
|
||||||
|
import org.qortal.asset.Asset;
|
||||||
|
import org.qortal.crosschain.BTCACCT;
|
||||||
import org.qortal.data.transaction.BaseTransactionData;
|
import org.qortal.data.transaction.BaseTransactionData;
|
||||||
|
import org.qortal.data.transaction.DeployAtTransactionData;
|
||||||
import org.qortal.data.transaction.PresenceTransactionData;
|
import org.qortal.data.transaction.PresenceTransactionData;
|
||||||
|
import org.qortal.data.transaction.TransactionData;
|
||||||
import org.qortal.data.transaction.PresenceTransactionData.PresenceType;
|
import org.qortal.data.transaction.PresenceTransactionData.PresenceType;
|
||||||
import org.qortal.group.Group;
|
import org.qortal.group.Group;
|
||||||
import org.qortal.repository.DataException;
|
import org.qortal.repository.DataException;
|
||||||
import org.qortal.repository.Repository;
|
import org.qortal.repository.Repository;
|
||||||
import org.qortal.repository.RepositoryManager;
|
import org.qortal.repository.RepositoryManager;
|
||||||
|
import org.qortal.test.common.BlockUtils;
|
||||||
import org.qortal.test.common.Common;
|
import org.qortal.test.common.Common;
|
||||||
import org.qortal.test.common.TransactionUtils;
|
import org.qortal.test.common.TransactionUtils;
|
||||||
|
import org.qortal.transaction.DeployAtTransaction;
|
||||||
import org.qortal.transaction.PresenceTransaction;
|
import org.qortal.transaction.PresenceTransaction;
|
||||||
import org.qortal.transaction.Transaction;
|
import org.qortal.transaction.Transaction;
|
||||||
import org.qortal.transaction.Transaction.ValidationResult;
|
import org.qortal.transaction.Transaction.ValidationResult;
|
||||||
|
import org.qortal.utils.NTP;
|
||||||
|
|
||||||
import com.google.common.primitives.Longs;
|
import com.google.common.primitives.Longs;
|
||||||
|
|
||||||
@ -23,6 +30,9 @@ import static org.junit.Assert.*;
|
|||||||
|
|
||||||
public class PresenceTests extends Common {
|
public class PresenceTests extends Common {
|
||||||
|
|
||||||
|
private static final byte[] BITCOIN_PKH = new byte[20];
|
||||||
|
private static final byte[] HASH_OF_SECRET_B = new byte[32];
|
||||||
|
|
||||||
private PrivateKeyAccount signer;
|
private PrivateKeyAccount signer;
|
||||||
private Repository repository;
|
private Repository repository;
|
||||||
|
|
||||||
@ -32,6 +42,31 @@ public class PresenceTests extends Common {
|
|||||||
|
|
||||||
this.repository = RepositoryManager.getRepository();
|
this.repository = RepositoryManager.getRepository();
|
||||||
this.signer = Common.getTestAccount(this.repository, "bob");
|
this.signer = Common.getTestAccount(this.repository, "bob");
|
||||||
|
|
||||||
|
// We need to create corresponding test trade offer
|
||||||
|
byte[] creationBytes = BTCACCT.buildQortalAT(this.signer.getAddress(), BITCOIN_PKH, HASH_OF_SECRET_B,
|
||||||
|
0L, 0L,
|
||||||
|
7 * 24 * 60 * 60);
|
||||||
|
|
||||||
|
long txTimestamp = NTP.getTime();
|
||||||
|
byte[] lastReference = this.signer.getLastReference();
|
||||||
|
|
||||||
|
long fee = 0;
|
||||||
|
String name = "QORT-BTC cross-chain trade";
|
||||||
|
String description = "Qortal-Bitcoin cross-chain trade";
|
||||||
|
String atType = "ACCT";
|
||||||
|
String tags = "QORT-BTC ACCT";
|
||||||
|
|
||||||
|
BaseTransactionData baseTransactionData = new BaseTransactionData(txTimestamp, Group.NO_GROUP, lastReference, this.signer.getPublicKey(), fee, null);
|
||||||
|
TransactionData deployAtTransactionData = new DeployAtTransactionData(baseTransactionData, name, description, atType, tags, creationBytes, 1L, Asset.QORT);
|
||||||
|
|
||||||
|
Transaction deployAtTransaction = new DeployAtTransaction(repository, deployAtTransactionData);
|
||||||
|
|
||||||
|
fee = deployAtTransaction.calcRecommendedFee();
|
||||||
|
deployAtTransactionData.setFee(fee);
|
||||||
|
|
||||||
|
TransactionUtils.signAndImportValid(this.repository, deployAtTransactionData, this.signer);
|
||||||
|
BlockUtils.mintBlock(this.repository);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@ -50,6 +85,9 @@ public class PresenceTests extends Common {
|
|||||||
byte[] timestampSignature = this.signer.sign(timestampBytes);
|
byte[] timestampSignature = this.signer.sign(timestampBytes);
|
||||||
|
|
||||||
assertTrue(isValid(Group.NO_GROUP, this.signer, timestamp, timestampSignature));
|
assertTrue(isValid(Group.NO_GROUP, this.signer, timestamp, timestampSignature));
|
||||||
|
|
||||||
|
PrivateKeyAccount nonTrader = Common.getTestAccount(repository, "alice");
|
||||||
|
assertFalse(isValid(Group.NO_GROUP, nonTrader, timestamp, timestampSignature));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -87,7 +125,7 @@ public class PresenceTests extends Common {
|
|||||||
timestampSignature = this.signer.sign(Longs.toByteArray(timestamp));
|
timestampSignature = this.signer.sign(Longs.toByteArray(timestamp));
|
||||||
|
|
||||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, creatorPublicKey, fee, null);
|
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, creatorPublicKey, fee, null);
|
||||||
PresenceTransactionData transactionData = new PresenceTransactionData(baseTransactionData, nonce, PresenceType.REWARD_SHARE, timestampSignature);
|
PresenceTransactionData transactionData = new PresenceTransactionData(baseTransactionData, nonce, PresenceType.TRADE_BOT, timestampSignature);
|
||||||
|
|
||||||
return new PresenceTransaction(this.repository, transactionData);
|
return new PresenceTransaction(this.repository, transactionData);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user