diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index efdc57ef..104a71d6 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -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(); diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataTransactionBuilder.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataTransactionBuilder.java index fbe93fd2..c12e4ce9 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataTransactionBuilder.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataTransactionBuilder.java @@ -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 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); diff --git a/src/main/java/org/qortal/data/transaction/ArbitraryTransactionData.java b/src/main/java/org/qortal/data/transaction/ArbitraryTransactionData.java index 9fc91465..5837dc3e 100644 --- a/src/main/java/org/qortal/data/transaction/ArbitraryTransactionData.java +++ b/src/main/java/org/qortal/data/transaction/ArbitraryTransactionData.java @@ -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 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; } diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java index 07a7ed05..c90af07c 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBArbitraryRepository.java @@ -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 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 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) { diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java index 35331119..447d4536 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -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; diff --git a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java index bcf4abd1..33be8203 100644 --- a/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java +++ b/src/main/java/org/qortal/repository/hsqldb/transaction/HSQLDBArbitraryTransactionRepository.java @@ -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 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); diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index 748b1fdc..658dd7ea 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -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 diff --git a/src/main/java/org/qortal/transform/transaction/ArbitraryTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/ArbitraryTransactionTransformer.java index e3827978..21eff286 100644 --- a/src/main/java/org/qortal/transform/transaction/ArbitraryTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/ArbitraryTransactionTransformer.java @@ -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(); diff --git a/src/test/java/org/qortal/test/arbitrary/ArbitraryDataTests.java b/src/test/java/org/qortal/test/arbitrary/ArbitraryDataTests.java index 0f3c3f50..3ea93264 100644 --- a/src/test/java/org/qortal/test/arbitrary/ArbitraryDataTests.java +++ b/src/test/java/org/qortal/test/arbitrary/ArbitraryDataTests.java @@ -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); diff --git a/src/test/java/org/qortal/test/arbitrary/ArbitraryTransactionTests.java b/src/test/java/org/qortal/test/arbitrary/ArbitraryTransactionTests.java index 4d0280b6..69e88b4f 100644 --- a/src/test/java/org/qortal/test/arbitrary/ArbitraryTransactionTests.java +++ b/src/test/java/org/qortal/test/arbitrary/ArbitraryTransactionTests.java @@ -42,7 +42,7 @@ public class ArbitraryTransactionTests extends Common { List 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); diff --git a/src/test/java/org/qortal/test/common/transaction/ArbitraryTestTransaction.java b/src/test/java/org/qortal/test/common/transaction/ArbitraryTestTransaction.java index c51b0a5b..f7981876 100644 --- a/src/test/java/org/qortal/test/common/transaction/ArbitraryTestTransaction.java +++ b/src/test/java/org/qortal/test/common/transaction/ArbitraryTestTransaction.java @@ -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 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); } }