forked from Qortal/qortal
Added "identifier" property to arbitrary transactions
Until now we have been limited to one data resource per name/service combination. This meant that each name could only have a single website, git repo, image, video, etc, and adding another would overwrite the previous data. The identifier property now allows an optional string to be supplied with each resource, therefore allowing an unlimited amount of resources per name/service combination. Some examples of what this will allow us to do: - Create a video library app which holds multiple videos per name - Same as above but for photos - Store multiple images against each name, such as an avatar, website thumbnails, video thumbnails, etc. This will be necessary for many "system level" features. - Attach multiple websites to each name. The default website (with blank/null identifier) would remain the entry point, but other websites could be hosted essentially as subdomains, and then linked from the default site. This also provides a means to go beyond the 500MB website size limit. Not all of these features will exist initially, but having this identifier included in the protocol layer allows them to be added at any time.
This commit is contained in:
parent
a0fe1a85f1
commit
991125034e
@ -353,11 +353,12 @@ public class ArbitraryResource {
|
||||
)
|
||||
public String post(@PathParam("service") String serviceString,
|
||||
@PathParam("name") String name,
|
||||
@QueryParam("identifier") String identifier,
|
||||
String path) {
|
||||
Security.checkApiCallAllowed(request);
|
||||
|
||||
// TODO: automatic PUT/PATCH
|
||||
return this.upload(Method.PUT, Service.valueOf(serviceString), name, path);
|
||||
return this.upload(Method.PUT, Service.valueOf(serviceString), name, identifier, path);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@ -388,10 +389,11 @@ public class ArbitraryResource {
|
||||
)
|
||||
public String put(@PathParam("service") String serviceString,
|
||||
@PathParam("name") String name,
|
||||
@QueryParam("identifier") String identifier,
|
||||
String path) {
|
||||
Security.checkApiCallAllowed(request);
|
||||
|
||||
return this.upload(Method.PUT, Service.valueOf(serviceString), name, path);
|
||||
return this.upload(Method.PUT, Service.valueOf(serviceString), name, identifier, path);
|
||||
}
|
||||
|
||||
@PATCH
|
||||
@ -422,14 +424,15 @@ public class ArbitraryResource {
|
||||
}
|
||||
)
|
||||
public String patch(@PathParam("service") String serviceString,
|
||||
@PathParam("name") String name,
|
||||
@PathParam("name") String name,
|
||||
@QueryParam("identifier") String identifier,
|
||||
String path) {
|
||||
Security.checkApiCallAllowed(request);
|
||||
|
||||
return this.upload(Method.PATCH, Service.valueOf(serviceString), name, path);
|
||||
return this.upload(Method.PATCH, Service.valueOf(serviceString), name, identifier, path);
|
||||
}
|
||||
|
||||
private String upload(Method method, Service service, String name, String path) {
|
||||
private String upload(Method method, Service service, String name, String identifier, String path) {
|
||||
// It's too dangerous to allow user-supplied file paths in weaker security contexts
|
||||
if (Settings.getInstance().isApiRestricted()) {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.NON_PRODUCTION);
|
||||
@ -452,7 +455,7 @@ public class ArbitraryResource {
|
||||
|
||||
try {
|
||||
ArbitraryDataTransactionBuilder transactionBuilder = new ArbitraryDataTransactionBuilder(
|
||||
publicKey58, Paths.get(path), name, method, service
|
||||
publicKey58, Paths.get(path), name, method, service, identifier
|
||||
);
|
||||
|
||||
ArbitraryTransactionData transactionData = transactionBuilder.build();
|
||||
|
@ -36,13 +36,16 @@ public class ArbitraryDataTransactionBuilder {
|
||||
private String name;
|
||||
private Method method;
|
||||
private Service service;
|
||||
private String identifier;
|
||||
|
||||
public ArbitraryDataTransactionBuilder(String publicKey58, Path path, String name, Method method, Service service) {
|
||||
public ArbitraryDataTransactionBuilder(String publicKey58, Path path, String name,
|
||||
Method method, Service service, String identifier) {
|
||||
this.publicKey58 = publicKey58;
|
||||
this.path = path;
|
||||
this.name = name;
|
||||
this.method = method;
|
||||
this.service = service;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public ArbitraryTransactionData build() throws DataException {
|
||||
@ -97,7 +100,7 @@ public class ArbitraryDataTransactionBuilder {
|
||||
final List<PaymentData> payments = new ArrayList<>();
|
||||
|
||||
ArbitraryTransactionData transactionData = new ArbitraryTransactionData(baseTransactionData,
|
||||
version, service, nonce, size, name, method,
|
||||
version, service, nonce, size, name, identifier, method,
|
||||
secret, compression, digest, dataType, chunkHashes, payments);
|
||||
|
||||
ArbitraryTransaction transaction = (ArbitraryTransaction) Transaction.fromData(repository, transactionData);
|
||||
|
@ -100,6 +100,7 @@ public class ArbitraryTransactionData extends TransactionData {
|
||||
private int size;
|
||||
|
||||
private String name;
|
||||
private String identifier;
|
||||
private Method method;
|
||||
private byte[] secret;
|
||||
private Compression compression;
|
||||
@ -125,7 +126,7 @@ public class ArbitraryTransactionData extends TransactionData {
|
||||
|
||||
public ArbitraryTransactionData(BaseTransactionData baseTransactionData,
|
||||
int version, Service service, int nonce, int size,
|
||||
String name, Method method, byte[] secret, Compression compression,
|
||||
String name, String identifier, Method method, byte[] secret, Compression compression,
|
||||
byte[] data, DataType dataType, byte[] chunkHashes, List<PaymentData> payments) {
|
||||
super(TransactionType.ARBITRARY, baseTransactionData);
|
||||
|
||||
@ -135,6 +136,7 @@ public class ArbitraryTransactionData extends TransactionData {
|
||||
this.nonce = nonce;
|
||||
this.size = size;
|
||||
this.name = name;
|
||||
this.identifier = identifier;
|
||||
this.method = method;
|
||||
this.secret = secret;
|
||||
this.compression = compression;
|
||||
@ -174,6 +176,10 @@ public class ArbitraryTransactionData extends TransactionData {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
return this.identifier;
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return this.method;
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository {
|
||||
String sql = "SELECT type, reference, signature, creator, created_when, fee, " +
|
||||
"tx_group_id, block_height, approval_status, approval_height, " +
|
||||
"version, nonce, service, size, is_data_raw, data, chunk_hashes, " +
|
||||
"name, update_method, secret, compression FROM ArbitraryTransactions " +
|
||||
"name, identifier, update_method, secret, compression FROM ArbitraryTransactions " +
|
||||
"JOIN Transactions USING (signature) " +
|
||||
"WHERE lower(name) = ? AND service = ? AND created_when >= ? " +
|
||||
"ORDER BY created_when ASC";
|
||||
@ -201,14 +201,15 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository {
|
||||
byte[] data = resultSet.getBytes(16);
|
||||
byte[] chunkHashes = resultSet.getBytes(17);
|
||||
String nameResult = resultSet.getString(18);
|
||||
Method method = Method.valueOf(resultSet.getInt(19));
|
||||
byte[] secret = resultSet.getBytes(20);
|
||||
Compression compression = Compression.valueOf(resultSet.getInt(21));
|
||||
String identifierResult = resultSet.getString(19);
|
||||
Method method = Method.valueOf(resultSet.getInt(20));
|
||||
byte[] secret = resultSet.getBytes(21);
|
||||
Compression compression = Compression.valueOf(resultSet.getInt(22));
|
||||
|
||||
List<PaymentData> payments = new ArrayList<>(); // TODO: this.getPaymentsFromSignature(baseTransactionData.getSignature());
|
||||
ArbitraryTransactionData transactionData = new ArbitraryTransactionData(baseTransactionData,
|
||||
version, serviceResult, nonce, size, nameResult, method, secret, compression, data,
|
||||
dataType, chunkHashes, payments);
|
||||
version, serviceResult, nonce, size, nameResult, identifierResult, method, secret,
|
||||
compression, data, dataType, chunkHashes, payments);
|
||||
|
||||
arbitraryTransactionData.add(transactionData);
|
||||
} while (resultSet.next());
|
||||
@ -226,7 +227,7 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository {
|
||||
sql.append("SELECT type, reference, signature, creator, created_when, fee, " +
|
||||
"tx_group_id, block_height, approval_status, approval_height, " +
|
||||
"version, nonce, service, size, is_data_raw, data, chunk_hashes, " +
|
||||
"name, update_method, secret, compression FROM ArbitraryTransactions " +
|
||||
"name, identifier, update_method, secret, compression FROM ArbitraryTransactions " +
|
||||
"JOIN Transactions USING (signature) " +
|
||||
"WHERE lower(name) = ? AND service = ?");
|
||||
|
||||
@ -274,14 +275,15 @@ public class HSQLDBArbitraryRepository implements ArbitraryRepository {
|
||||
byte[] data = resultSet.getBytes(16);
|
||||
byte[] chunkHashes = resultSet.getBytes(17);
|
||||
String nameResult = resultSet.getString(18);
|
||||
Method methodResult = Method.valueOf(resultSet.getInt(19));
|
||||
byte[] secret = resultSet.getBytes(20);
|
||||
Compression compression = Compression.valueOf(resultSet.getInt(21));
|
||||
String identifierResult = resultSet.getString(19);
|
||||
Method methodResult = Method.valueOf(resultSet.getInt(20));
|
||||
byte[] secret = resultSet.getBytes(21);
|
||||
Compression compression = Compression.valueOf(resultSet.getInt(22));
|
||||
|
||||
List<PaymentData> payments = new ArrayList<>(); // TODO: this.getPaymentsFromSignature(baseTransactionData.getSignature());
|
||||
ArbitraryTransactionData transactionData = new ArbitraryTransactionData(baseTransactionData,
|
||||
version, serviceResult, nonce, size, nameResult, methodResult, secret, compression, data,
|
||||
dataType, chunkHashes, payments);
|
||||
version, serviceResult, nonce, size, nameResult, identifierResult, methodResult, secret,
|
||||
compression, data, dataType, chunkHashes, payments);
|
||||
|
||||
return transactionData;
|
||||
} catch (SQLException e) {
|
||||
|
@ -920,6 +920,8 @@ public class HSQLDBDatabaseUpdates {
|
||||
stmt.execute("ALTER TABLE ArbitraryTransactions ADD secret VARBINARY(32)");
|
||||
// We want to support compressed and uncompressed data, as well as different compression algorithms
|
||||
stmt.execute("ALTER TABLE ArbitraryTransactions ADD compression INTEGER NOT NULL DEFAULT 0");
|
||||
// An optional identifier string can be used to allow more than one resource per user/service combo
|
||||
stmt.execute("ALTER TABLE ArbitraryTransactions ADD identifier VARCHAR(64)");
|
||||
// For finding transactions by registered name
|
||||
stmt.execute("CREATE INDEX ArbitraryNameIndex ON ArbitraryTransactions (name)");
|
||||
break;
|
||||
|
@ -21,7 +21,8 @@ public class HSQLDBArbitraryTransactionRepository extends HSQLDBTransactionRepos
|
||||
|
||||
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
|
||||
String sql = "SELECT version, nonce, service, size, is_data_raw, data, chunk_hashes, " +
|
||||
"name, update_method, secret, compression from ArbitraryTransactions WHERE signature = ?";
|
||||
"name, identifier, update_method, secret, compression from ArbitraryTransactions " +
|
||||
"WHERE signature = ?";
|
||||
|
||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
|
||||
if (resultSet == null)
|
||||
@ -36,13 +37,14 @@ public class HSQLDBArbitraryTransactionRepository extends HSQLDBTransactionRepos
|
||||
byte[] data = resultSet.getBytes(6);
|
||||
byte[] chunkHashes = resultSet.getBytes(7);
|
||||
String name = resultSet.getString(8);
|
||||
ArbitraryTransactionData.Method method = ArbitraryTransactionData.Method.valueOf(resultSet.getInt(9));
|
||||
byte[] secret = resultSet.getBytes(10);
|
||||
ArbitraryTransactionData.Compression compression = ArbitraryTransactionData.Compression.valueOf(resultSet.getInt(11));
|
||||
String identifier = resultSet.getString(9);
|
||||
ArbitraryTransactionData.Method method = ArbitraryTransactionData.Method.valueOf(resultSet.getInt(10));
|
||||
byte[] secret = resultSet.getBytes(11);
|
||||
ArbitraryTransactionData.Compression compression = ArbitraryTransactionData.Compression.valueOf(resultSet.getInt(12));
|
||||
|
||||
List<PaymentData> payments = this.getPaymentsFromSignature(baseTransactionData.getSignature());
|
||||
return new ArbitraryTransactionData(baseTransactionData, version, service, nonce, size, name, method,
|
||||
secret, compression, data, dataType, chunkHashes, payments);
|
||||
return new ArbitraryTransactionData(baseTransactionData, version, service, nonce, size, name,
|
||||
identifier, method, secret, compression, data, dataType, chunkHashes, payments);
|
||||
} catch (SQLException e) {
|
||||
throw new DataException("Unable to fetch arbitrary transaction from repository", e);
|
||||
}
|
||||
@ -63,8 +65,8 @@ public class HSQLDBArbitraryTransactionRepository extends HSQLDBTransactionRepos
|
||||
.bind("nonce", arbitraryTransactionData.getNonce()).bind("size", arbitraryTransactionData.getSize())
|
||||
.bind("is_data_raw", arbitraryTransactionData.getDataType() == DataType.RAW_DATA).bind("data", arbitraryTransactionData.getData())
|
||||
.bind("chunk_hashes", arbitraryTransactionData.getChunkHashes()).bind("name", arbitraryTransactionData.getName())
|
||||
.bind("update_method", arbitraryTransactionData.getMethod().value).bind("secret", arbitraryTransactionData.getSecret())
|
||||
.bind("compression", arbitraryTransactionData.getCompression().value);
|
||||
.bind("identifier", arbitraryTransactionData.getIdentifier()).bind("update_method", arbitraryTransactionData.getMethod().value)
|
||||
.bind("secret", arbitraryTransactionData.getSecret()).bind("compression", arbitraryTransactionData.getCompression().value);
|
||||
|
||||
try {
|
||||
saveHelper.execute(this.repository);
|
||||
|
@ -35,6 +35,7 @@ public class ArbitraryTransaction extends Transaction {
|
||||
public static final int POW_MIN_DIFFICULTY = 12; // leading zero bits
|
||||
public static final int POW_MAX_DIFFICULTY = 19; // leading zero bits
|
||||
public static final long MAX_FILE_SIZE = ArbitraryDataFile.MAX_FILE_SIZE;
|
||||
public static final int MAX_IDENTIFIER_LENGTH = 64;
|
||||
|
||||
// Constructors
|
||||
|
||||
|
@ -35,14 +35,15 @@ public class ArbitraryTransactionTransformer extends TransactionTransformer {
|
||||
private static final int CHUNKS_SIZE_LENGTH = INT_LENGTH;
|
||||
private static final int NUMBER_PAYMENTS_LENGTH = INT_LENGTH;
|
||||
private static final int NAME_SIZE_LENGTH = INT_LENGTH;
|
||||
private static final int IDENTIFIER_SIZE_LENGTH = INT_LENGTH;
|
||||
private static final int COMPRESSION_LENGTH = INT_LENGTH;
|
||||
private static final int METHOD_LENGTH = INT_LENGTH;
|
||||
private static final int SECRET_LENGTH = INT_LENGTH;
|
||||
|
||||
private static final int EXTRAS_LENGTH = SERVICE_LENGTH + DATA_TYPE_LENGTH + DATA_SIZE_LENGTH;
|
||||
|
||||
private static final int EXTRAS_V5_LENGTH = NONCE_LENGTH + NAME_SIZE_LENGTH + METHOD_LENGTH + SECRET_LENGTH +
|
||||
COMPRESSION_LENGTH + RAW_DATA_SIZE_LENGTH + CHUNKS_SIZE_LENGTH;
|
||||
private static final int EXTRAS_V5_LENGTH = NONCE_LENGTH + NAME_SIZE_LENGTH + IDENTIFIER_SIZE_LENGTH +
|
||||
METHOD_LENGTH + SECRET_LENGTH + COMPRESSION_LENGTH + RAW_DATA_SIZE_LENGTH + CHUNKS_SIZE_LENGTH;
|
||||
|
||||
protected static final TransactionLayout layout;
|
||||
|
||||
@ -57,6 +58,8 @@ public class ArbitraryTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
layout.add("name length", TransformationType.INT); // Version 5+
|
||||
layout.add("name", TransformationType.DATA); // Version 5+
|
||||
layout.add("identifier length", TransformationType.INT); // Version 5+
|
||||
layout.add("identifier", TransformationType.DATA); // Version 5+
|
||||
layout.add("method", TransformationType.INT); // Version 5+
|
||||
layout.add("secret length", TransformationType.INT); // Version 5+
|
||||
layout.add("secret", TransformationType.DATA); // Version 5+
|
||||
@ -94,6 +97,7 @@ public class ArbitraryTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
int nonce = 0;
|
||||
String name = null;
|
||||
String identifier = null;
|
||||
ArbitraryTransactionData.Method method = null;
|
||||
byte[] secret = null;
|
||||
ArbitraryTransactionData.Compression compression = null;
|
||||
@ -103,6 +107,8 @@ public class ArbitraryTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
name = Serialization.deserializeSizedString(byteBuffer, Name.MAX_NAME_SIZE);
|
||||
|
||||
identifier = Serialization.deserializeSizedString(byteBuffer, ArbitraryTransaction.MAX_IDENTIFIER_LENGTH);
|
||||
|
||||
method = ArbitraryTransactionData.Method.valueOf(byteBuffer.getInt());
|
||||
|
||||
int secretLength = byteBuffer.getInt();
|
||||
@ -160,18 +166,20 @@ public class ArbitraryTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, senderPublicKey, fee, signature);
|
||||
|
||||
return new ArbitraryTransactionData(baseTransactionData, version, service, nonce, size, name, method, secret, compression, data, dataType, chunkHashes, payments);
|
||||
return new ArbitraryTransactionData(baseTransactionData, version, service, nonce, size, name, identifier,
|
||||
method, secret, compression, data, dataType, chunkHashes, payments);
|
||||
}
|
||||
|
||||
public static int getDataLength(TransactionData transactionData) throws TransformationException {
|
||||
ArbitraryTransactionData arbitraryTransactionData = (ArbitraryTransactionData) transactionData;
|
||||
|
||||
int nameLength = (arbitraryTransactionData.getName() != null) ? Utf8.encodedLength(arbitraryTransactionData.getName()) : 0;
|
||||
int identifierLength = (arbitraryTransactionData.getIdentifier() != null) ? Utf8.encodedLength(arbitraryTransactionData.getIdentifier()) : 0;
|
||||
int secretLength = (arbitraryTransactionData.getSecret() != null) ? arbitraryTransactionData.getSecret().length : 0;
|
||||
int dataLength = (arbitraryTransactionData.getData() != null) ? arbitraryTransactionData.getData().length : 0;
|
||||
int chunkHashesLength = (arbitraryTransactionData.getChunkHashes() != null) ? arbitraryTransactionData.getChunkHashes().length : 0;
|
||||
|
||||
int length = getBaseLength(transactionData) + EXTRAS_LENGTH + nameLength + secretLength + dataLength + chunkHashesLength;
|
||||
int length = getBaseLength(transactionData) + EXTRAS_LENGTH + nameLength + identifierLength + secretLength + dataLength + chunkHashesLength;
|
||||
|
||||
if (arbitraryTransactionData.getVersion() >= 5) {
|
||||
length += EXTRAS_V5_LENGTH;
|
||||
@ -196,6 +204,8 @@ public class ArbitraryTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
Serialization.serializeSizedString(bytes, arbitraryTransactionData.getName());
|
||||
|
||||
Serialization.serializeSizedString(bytes, arbitraryTransactionData.getIdentifier());
|
||||
|
||||
bytes.write(Ints.toByteArray(arbitraryTransactionData.getMethod().value));
|
||||
|
||||
byte[] secret = arbitraryTransactionData.getSecret();
|
||||
@ -265,6 +275,8 @@ public class ArbitraryTransactionTransformer extends TransactionTransformer {
|
||||
|
||||
Serialization.serializeSizedString(bytes, arbitraryTransactionData.getName());
|
||||
|
||||
Serialization.serializeSizedString(bytes, arbitraryTransactionData.getIdentifier());
|
||||
|
||||
bytes.write(Ints.toByteArray(arbitraryTransactionData.getMethod().value));
|
||||
|
||||
byte[] secret = arbitraryTransactionData.getSecret();
|
||||
|
@ -43,6 +43,7 @@ public class ArbitraryDataTests extends Common {
|
||||
PrivateKeyAccount alice = Common.getTestAccount(repository, "alice");
|
||||
String publicKey58 = Base58.encode(alice.getPublicKey());
|
||||
String name = "TEST"; // Can be anything for this test
|
||||
String identifier = null; // Not used for this test
|
||||
Service service = Service.WEBSITE; // Can be anything for this test
|
||||
|
||||
// Register the name to Alice
|
||||
@ -51,15 +52,15 @@ public class ArbitraryDataTests extends Common {
|
||||
|
||||
// Create PUT transaction
|
||||
Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
|
||||
this.createAndMintTxn(repository, publicKey58, path1, name, Method.PUT, service, alice);
|
||||
this.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice);
|
||||
|
||||
// Create PATCH transaction
|
||||
Path path2 = Paths.get("src/test/resources/arbitrary/demo2");
|
||||
this.createAndMintTxn(repository, publicKey58, path2, name, Method.PATCH, service, alice);
|
||||
this.createAndMintTxn(repository, publicKey58, path2, name, identifier, Method.PATCH, service, alice);
|
||||
|
||||
// Create another PATCH transaction
|
||||
Path path3 = Paths.get("src/test/resources/arbitrary/demo3");
|
||||
this.createAndMintTxn(repository, publicKey58, path3, name, Method.PATCH, service, alice);
|
||||
this.createAndMintTxn(repository, publicKey58, path3, name, identifier, Method.PATCH, service, alice);
|
||||
|
||||
// Now build the latest data state for this name
|
||||
ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader(name, ResourceIdType.NAME, service);
|
||||
@ -90,12 +91,13 @@ public class ArbitraryDataTests extends Common {
|
||||
PrivateKeyAccount alice = Common.getTestAccount(repository, "alice");
|
||||
String publicKey58 = Base58.encode(alice.getPublicKey());
|
||||
String name = "TEST"; // Can be anything for this test
|
||||
String identifier = null; // Not used for this test
|
||||
Service service = Service.WEBSITE; // Can be anything for this test
|
||||
|
||||
// Create PATCH transaction, ensuring that an exception is thrown
|
||||
try {
|
||||
Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
|
||||
this.createAndMintTxn(repository, publicKey58, path1, name, Method.PATCH, service, alice);
|
||||
this.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PATCH, service, alice);
|
||||
fail("Creating transaction should fail due to nonexistent PUT transaction");
|
||||
|
||||
} catch (DataException expectedException) {
|
||||
@ -107,11 +109,12 @@ public class ArbitraryDataTests extends Common {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNameDoesNotExist() throws DataException, IOException {
|
||||
public void testNameDoesNotExist() throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
PrivateKeyAccount alice = Common.getTestAccount(repository, "alice");
|
||||
String publicKey58 = Base58.encode(alice.getPublicKey());
|
||||
String name = "TEST"; // Can be anything for this test
|
||||
String identifier = null; // Not used for this test
|
||||
Service service = Service.WEBSITE; // Can be anything for this test
|
||||
|
||||
// Ensure the name doesn't exist
|
||||
@ -120,7 +123,7 @@ public class ArbitraryDataTests extends Common {
|
||||
// Create PUT transaction, ensuring that an exception is thrown
|
||||
try {
|
||||
Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
|
||||
this.createAndMintTxn(repository, publicKey58, path1, name, Method.PUT, service, alice);
|
||||
this.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice);
|
||||
fail("Creating transaction should fail due to the name being unregistered");
|
||||
|
||||
} catch (DataException expectedException) {
|
||||
@ -130,10 +133,11 @@ public class ArbitraryDataTests extends Common {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateResourceOwnedByAnotherCreator() throws DataException, IOException {
|
||||
public void testUpdateResourceOwnedByAnotherCreator() throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
PrivateKeyAccount alice = Common.getTestAccount(repository, "alice");
|
||||
String name = "TEST"; // Can be anything for this test
|
||||
String identifier = null; // Not used for this test
|
||||
Service service = Service.WEBSITE; // Can be anything for this test
|
||||
|
||||
// Register the name to Alice
|
||||
@ -142,7 +146,7 @@ public class ArbitraryDataTests extends Common {
|
||||
|
||||
// Create PUT transaction
|
||||
Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
|
||||
this.createAndMintTxn(repository, Base58.encode(alice.getPublicKey()), path1, name, Method.PUT, service, alice);
|
||||
this.createAndMintTxn(repository, Base58.encode(alice.getPublicKey()), path1, name, identifier, Method.PUT, service, alice);
|
||||
|
||||
// Bob attempts to update Alice's data
|
||||
PrivateKeyAccount bob = Common.getTestAccount(repository, "bob");
|
||||
@ -150,7 +154,7 @@ public class ArbitraryDataTests extends Common {
|
||||
// Create PATCH transaction, ensuring that an exception is thrown
|
||||
try {
|
||||
Path path2 = Paths.get("src/test/resources/arbitrary/demo2");
|
||||
this.createAndMintTxn(repository, Base58.encode(bob.getPublicKey()), path2, name, Method.PATCH, service, bob);
|
||||
this.createAndMintTxn(repository, Base58.encode(bob.getPublicKey()), path2, name, identifier, Method.PATCH, service, bob);
|
||||
fail("Creating transaction should fail due to the name being registered to Alice instead of Bob");
|
||||
|
||||
} catch (DataException expectedException) {
|
||||
@ -165,6 +169,7 @@ public class ArbitraryDataTests extends Common {
|
||||
PrivateKeyAccount alice = Common.getTestAccount(repository, "alice");
|
||||
String publicKey58 = Base58.encode(alice.getPublicKey());
|
||||
String name = "TEST"; // Can be anything for this test
|
||||
String identifier = null; // Not used for this test
|
||||
Service service = Service.WEBSITE; // Can be anything for this test
|
||||
|
||||
// Register the name to Alice
|
||||
@ -173,7 +178,7 @@ public class ArbitraryDataTests extends Common {
|
||||
|
||||
// Create PUT transaction
|
||||
Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
|
||||
this.createAndMintTxn(repository, publicKey58, path1, name, Method.PUT, service, alice);
|
||||
this.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice);
|
||||
|
||||
// Now build the latest data state for this name
|
||||
ArbitraryDataReader arbitraryDataReader1 = new ArbitraryDataReader(name, ResourceIdType.NAME, service);
|
||||
@ -184,7 +189,7 @@ public class ArbitraryDataTests extends Common {
|
||||
|
||||
// Create PATCH transaction
|
||||
Path path2 = Paths.get("src/test/resources/arbitrary/demo2");
|
||||
this.createAndMintTxn(repository, publicKey58, path2, name, Method.PATCH, service, alice);
|
||||
this.createAndMintTxn(repository, publicKey58, path2, name, identifier, Method.PATCH, service, alice);
|
||||
|
||||
// Rebuild the latest state
|
||||
ArbitraryDataReader arbitraryDataReader2 = new ArbitraryDataReader(name, ResourceIdType.NAME, service);
|
||||
@ -203,10 +208,12 @@ public class ArbitraryDataTests extends Common {
|
||||
}
|
||||
}
|
||||
|
||||
private void createAndMintTxn(Repository repository, String publicKey58, Path path, String name,
|
||||
private void createAndMintTxn(Repository repository, String publicKey58, Path path, String name, String identifier,
|
||||
Method method, Service service, PrivateKeyAccount account) throws DataException {
|
||||
|
||||
ArbitraryDataTransactionBuilder txnBuilder = new ArbitraryDataTransactionBuilder(publicKey58, path, name, method, service);
|
||||
ArbitraryDataTransactionBuilder txnBuilder = new ArbitraryDataTransactionBuilder(
|
||||
publicKey58, path, name, method, service, identifier);
|
||||
|
||||
ArbitraryTransactionData transactionData = txnBuilder.build();
|
||||
Transaction.ValidationResult result = TransactionUtils.signAndImport(repository, transactionData, account);
|
||||
assertEquals(Transaction.ValidationResult.OK, result);
|
||||
|
@ -42,7 +42,7 @@ public class ArbitraryTransactionTests extends Common {
|
||||
List<PaymentData> payments = new ArrayList<>();
|
||||
|
||||
ArbitraryTransactionData transactionData = new ArbitraryTransactionData(TestTransaction.generateBase(alice),
|
||||
5, service, 0, 0, null, method,
|
||||
5, service, 0, 0, null, null, method,
|
||||
null, compression, null, dataType, null, payments);
|
||||
|
||||
ArbitraryTransaction transaction = (ArbitraryTransaction) Transaction.fromData(repository, transactionData);
|
||||
|
@ -21,6 +21,7 @@ public class ArbitraryTestTransaction extends TestTransaction {
|
||||
final int nonce = 0;
|
||||
final int size = 4 * 1024 * 1024;
|
||||
final String name = "TEST";
|
||||
final String identifier = "qortal_avatar";
|
||||
final ArbitraryTransactionData.Method method = ArbitraryTransactionData.Method.PUT;
|
||||
|
||||
final byte[] secret = new byte[32];
|
||||
@ -43,8 +44,8 @@ public class ArbitraryTestTransaction extends TestTransaction {
|
||||
List<PaymentData> payments = new ArrayList<>();
|
||||
payments.add(new PaymentData(recipient, assetId, amount));
|
||||
|
||||
return new ArbitraryTransactionData(generateBase(account), version, service, nonce, size, name, method,
|
||||
secret, compression, data, dataType, chunkHashes, payments);
|
||||
return new ArbitraryTransactionData(generateBase(account), version, service, nonce, size,name, identifier,
|
||||
method, secret, compression, data, dataType, chunkHashes, payments);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user