Registered names: changing 'owner' and allowing renaming.

REGISTER_NAME has an "owner" field which can be different from the actual
registrant (transaction creator's public key, used for signing transaction).

This allowed people to register names to be owned by someone else, thus breaking
the whole "one name per account" aspect.

So now "owner" is removed from REGISTER_NAME, and the actual owner address is
derived from transaction creator's public key, as you would expect.

Similarly, UPDATE_NAME has a corresponding "newOwner" field which has been removed.

In addition, UPDATE_NAME now allows users to change their registered name using a new
"newName" field.

Various changes made to DB, Name class, etc. to accomodate above, along with some minor
bug-fixes and comment improvements/corrections.

Needs new unit tests to cover both new functionality and old!
This commit is contained in:
catbref 2020-05-13 10:19:56 +01:00
parent f29ae656b9
commit d9f784ed2b
16 changed files with 123 additions and 103 deletions

View File

@ -66,6 +66,10 @@ public class NameData {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getData() {
return this.data;
}

View File

@ -19,8 +19,6 @@ public class RegisterNameTransactionData extends TransactionData {
// Properties
@Schema(description = "registrant's public key", example = "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP")
private byte[] registrantPublicKey;
@Schema(description = "new owner's address", example = "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v")
private String owner;
@Schema(description = "requested name", example = "my-name")
private String name;
@Schema(description = "simple name-related info in JSON format", example = "{ \"age\": 30 }")
@ -38,11 +36,10 @@ public class RegisterNameTransactionData extends TransactionData {
}
/** From repository */
public RegisterNameTransactionData(BaseTransactionData baseTransactionData, String owner, String name, String data) {
public RegisterNameTransactionData(BaseTransactionData baseTransactionData, String name, String data) {
super(TransactionType.REGISTER_NAME, baseTransactionData);
this.registrantPublicKey = baseTransactionData.creatorPublicKey;
this.owner = owner;
this.name = name;
this.data = data;
}
@ -53,10 +50,6 @@ public class RegisterNameTransactionData extends TransactionData {
return this.registrantPublicKey;
}
public String getOwner() {
return this.owner;
}
public String getName() {
return this.name;
}

View File

@ -17,10 +17,10 @@ public class UpdateNameTransactionData extends TransactionData {
// Properties
@Schema(description = "owner's public key", example = "2tiMr5LTpaWCgbRvkPK8TFd7k63DyHJMMFFsz9uBf1ZP")
private byte[] ownerPublicKey;
@Schema(description = "new owner's address", example = "QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v")
private String newOwner;
@Schema(description = "which name to update", example = "my-name")
private String name;
@Schema(description = "new name", example = "my-new-name")
private String newName;
@Schema(description = "replacement simple name-related info in JSON format", example = "{ \"age\": 30 }")
private String newData;
// For internal use when orphaning
@ -40,19 +40,19 @@ public class UpdateNameTransactionData extends TransactionData {
}
/** From repository */
public UpdateNameTransactionData(BaseTransactionData baseTransactionData, String newOwner, String name, String newData, byte[] nameReference) {
public UpdateNameTransactionData(BaseTransactionData baseTransactionData, String name, String newName, String newData, byte[] nameReference) {
super(TransactionType.UPDATE_NAME, baseTransactionData);
this.ownerPublicKey = baseTransactionData.creatorPublicKey;
this.newOwner = newOwner;
this.name = name;
this.newName = newName;
this.newData = newData;
this.nameReference = nameReference;
}
/** From network/API */
public UpdateNameTransactionData(BaseTransactionData baseTransactionData, String newOwner, String name, String newData) {
this(baseTransactionData, newOwner, name, newData, null);
public UpdateNameTransactionData(BaseTransactionData baseTransactionData, String name, String newName, String newData) {
this(baseTransactionData, name, newName, newData, null);
}
// Getters / setters
@ -61,14 +61,14 @@ public class UpdateNameTransactionData extends TransactionData {
return this.ownerPublicKey;
}
public String getNewOwner() {
return this.newOwner;
}
public String getName() {
return this.name;
}
public String getNewName() {
return this.newName;
}
public String getNewData() {
return this.newData;
}

View File

@ -3,6 +3,7 @@ package org.qortal.naming;
import org.qortal.account.Account;
import org.qortal.account.PublicKeyAccount;
import org.qortal.asset.Asset;
import org.qortal.crypto.Crypto;
import org.qortal.data.naming.NameData;
import org.qortal.data.transaction.BuyNameTransactionData;
import org.qortal.data.transaction.CancelSellNameTransactionData;
@ -20,6 +21,7 @@ public class Name {
private NameData nameData;
// Useful constants
public static final int MIN_NAME_SIZE = 3;
public static final int MAX_NAME_SIZE = 400;
public static final int MAX_DATA_SIZE = 4000;
@ -33,7 +35,10 @@ public class Name {
*/
public Name(Repository repository, RegisterNameTransactionData registerNameTransactionData) {
this.repository = repository;
this.nameData = new NameData(registerNameTransactionData.getOwner(),
String owner = Crypto.toAddress(registerNameTransactionData.getRegistrantPublicKey());
this.nameData = new NameData(owner,
registerNameTransactionData.getName(), registerNameTransactionData.getData(), registerNameTransactionData.getTimestamp(),
registerNameTransactionData.getSignature(), registerNameTransactionData.getTxGroupId());
}
@ -66,23 +71,31 @@ public class Name {
throw new DataException("Unable to revert name transaction as referenced transaction not found in repository");
switch (previousTransactionData.getType()) {
case REGISTER_NAME:
case REGISTER_NAME: {
RegisterNameTransactionData previousRegisterNameTransactionData = (RegisterNameTransactionData) previousTransactionData;
this.nameData.setOwner(previousRegisterNameTransactionData.getOwner());
this.nameData.setName(previousRegisterNameTransactionData.getName());
this.nameData.setData(previousRegisterNameTransactionData.getData());
break;
}
case UPDATE_NAME:
case UPDATE_NAME: {
UpdateNameTransactionData previousUpdateNameTransactionData = (UpdateNameTransactionData) previousTransactionData;
this.nameData.setData(previousUpdateNameTransactionData.getNewData());
this.nameData.setOwner(previousUpdateNameTransactionData.getNewOwner());
break;
case BUY_NAME:
if (!previousUpdateNameTransactionData.getNewName().isBlank())
this.nameData.setName(previousUpdateNameTransactionData.getNewName());
if (!previousUpdateNameTransactionData.getNewData().isEmpty())
this.nameData.setData(previousUpdateNameTransactionData.getNewData());
break;
}
case BUY_NAME: {
BuyNameTransactionData previousBuyNameTransactionData = (BuyNameTransactionData) previousTransactionData;
Account buyer = new PublicKeyAccount(this.repository, previousBuyNameTransactionData.getBuyerPublicKey());
this.nameData.setOwner(buyer.getAddress());
break;
}
default:
throw new IllegalStateException("Unable to revert name transaction due to unsupported referenced transaction");
@ -96,9 +109,12 @@ public class Name {
// New name reference is this transaction's signature
this.nameData.setReference(updateNameTransactionData.getSignature());
// Update Name's owner and data
this.nameData.setOwner(updateNameTransactionData.getNewOwner());
this.nameData.setData(updateNameTransactionData.getNewData());
// Update name and data where appropriate
if (!updateNameTransactionData.getNewName().isEmpty())
this.nameData.setOwner(updateNameTransactionData.getNewName());
if (!updateNameTransactionData.getNewData().isEmpty())
this.nameData.setData(updateNameTransactionData.getNewData());
// Save updated name data
this.repository.getNameRepository().save(this.nameData);

View File

@ -294,11 +294,11 @@ public class HSQLDBDatabaseUpdates {
// Register Name Transactions
stmt.execute("CREATE TABLE RegisterNameTransactions (signature Signature, registrant QortalPublicKey NOT NULL, name RegisteredName NOT NULL, "
+ "owner QortalAddress NOT NULL, data NameData NOT NULL, " + TRANSACTION_KEYS + ")");
+ "data NameData NOT NULL, " + TRANSACTION_KEYS + ")");
// Update Name Transactions
stmt.execute("CREATE TABLE UpdateNameTransactions (signature Signature, owner QortalPublicKey NOT NULL, name RegisteredName NOT NULL, "
+ "new_owner QortalAddress NOT NULL, new_data NameData NOT NULL, name_reference Signature, " + TRANSACTION_KEYS + ")");
+ "new_name RegisteredName NOT NULL, new_data NameData NOT NULL, name_reference Signature, " + TRANSACTION_KEYS + ")");
// Sell Name Transactions
stmt.execute("CREATE TABLE SellNameTransactions (signature Signature, owner QortalPublicKey NOT NULL, name RegisteredName NOT NULL, "

View File

@ -17,17 +17,16 @@ public class HSQLDBRegisterNameTransactionRepository extends HSQLDBTransactionRe
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
String sql = "SELECT owner, name, data FROM RegisterNameTransactions WHERE signature = ?";
String sql = "SELECT name, data FROM RegisterNameTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)
return null;
String owner = resultSet.getString(1);
String name = resultSet.getString(2);
String data = resultSet.getString(3);
String name = resultSet.getString(1);
String data = resultSet.getString(2);
return new RegisterNameTransactionData(baseTransactionData, owner, name, data);
return new RegisterNameTransactionData(baseTransactionData, name, data);
} catch (SQLException e) {
throw new DataException("Unable to fetch register name transaction from repository", e);
}
@ -40,8 +39,7 @@ public class HSQLDBRegisterNameTransactionRepository extends HSQLDBTransactionRe
HSQLDBSaver saveHelper = new HSQLDBSaver("RegisterNameTransactions");
saveHelper.bind("signature", registerNameTransactionData.getSignature()).bind("registrant", registerNameTransactionData.getRegistrantPublicKey())
.bind("owner", registerNameTransactionData.getOwner()).bind("name", registerNameTransactionData.getName())
.bind("data", registerNameTransactionData.getData());
.bind("name", registerNameTransactionData.getName()).bind("data", registerNameTransactionData.getData());
try {
saveHelper.execute(this.repository);

View File

@ -17,18 +17,18 @@ public class HSQLDBUpdateNameTransactionRepository extends HSQLDBTransactionRepo
}
TransactionData fromBase(BaseTransactionData baseTransactionData) throws DataException {
String sql = "SELECT new_owner, name, new_data, name_reference FROM UpdateNameTransactions WHERE signature = ?";
String sql = "SELECT name, new_name, new_data, name_reference FROM UpdateNameTransactions WHERE signature = ?";
try (ResultSet resultSet = this.repository.checkedExecute(sql, baseTransactionData.getSignature())) {
if (resultSet == null)
return null;
String newOwner = resultSet.getString(1);
String name = resultSet.getString(2);
String name = resultSet.getString(1);
String newName = resultSet.getString(2);
String newData = resultSet.getString(3);
byte[] nameReference = resultSet.getBytes(4);
return new UpdateNameTransactionData(baseTransactionData, newOwner, name, newData, nameReference);
return new UpdateNameTransactionData(baseTransactionData, name, newName, newData, nameReference);
} catch (SQLException e) {
throw new DataException("Unable to fetch update name transaction from repository", e);
}
@ -41,7 +41,7 @@ public class HSQLDBUpdateNameTransactionRepository extends HSQLDBTransactionRepo
HSQLDBSaver saveHelper = new HSQLDBSaver("UpdateNameTransactions");
saveHelper.bind("signature", updateNameTransactionData.getSignature()).bind("owner", updateNameTransactionData.getOwnerPublicKey())
.bind("new_owner", updateNameTransactionData.getNewOwner()).bind("name", updateNameTransactionData.getName())
.bind("name", updateNameTransactionData.getName()).bind("new_name", updateNameTransactionData.getNewName())
.bind("new_data", updateNameTransactionData.getNewData()).bind("name_reference", updateNameTransactionData.getNameReference());
try {

View File

@ -5,6 +5,7 @@ import java.util.List;
import org.qortal.account.Account;
import org.qortal.asset.Asset;
import org.qortal.block.BlockChain;
import org.qortal.crypto.Crypto;
import org.qortal.data.naming.NameData;
import org.qortal.data.transaction.BuyNameTransactionData;
@ -54,7 +55,7 @@ public class BuyNameTransaction extends Transaction {
// Check name size bounds
int nameLength = Utf8.encodedLength(name);
if (nameLength < 1 || nameLength > Name.MAX_NAME_SIZE)
if (nameLength < Name.MIN_NAME_SIZE || nameLength > Name.MAX_NAME_SIZE)
return ValidationResult.INVALID_NAME_LENGTH;
// Check name is lowercase
@ -76,6 +77,11 @@ public class BuyNameTransaction extends Transaction {
if (buyer.getAddress().equals(nameData.getOwner()))
return ValidationResult.BUYER_ALREADY_OWNER;
// If accounts are only allowed one registered name then check for this
if (BlockChain.getInstance().oneNamePerAccount()
&& !this.repository.getNameRepository().getNamesByOwner(buyer.getAddress()).isEmpty())
return ValidationResult.MULTIPLE_NAMES_FORBIDDEN;
// Check expected seller currently owns name
if (!this.buyNameTransactionData.getSeller().equals(nameData.getOwner()))
return ValidationResult.INVALID_SELLER;
@ -84,7 +90,7 @@ public class BuyNameTransaction extends Transaction {
if (this.buyNameTransactionData.getAmount() != nameData.getSalePrice())
return ValidationResult.INVALID_AMOUNT;
// Check issuer has enough funds
// Check buyer has enough funds
if (buyer.getConfirmedBalance(Asset.QORT) < this.buyNameTransactionData.getFee())
return ValidationResult.NO_BALANCE;
@ -93,21 +99,21 @@ public class BuyNameTransaction extends Transaction {
@Override
public void process() throws DataException {
// Update Name
// Buy Name
Name name = new Name(this.repository, this.buyNameTransactionData.getName());
name.buy(this.buyNameTransactionData);
// Save transaction with updated "name reference" pointing to previous transaction that updated name
// Save transaction with updated "name reference" pointing to previous transaction that changed name
this.repository.getTransactionRepository().save(this.buyNameTransactionData);
}
@Override
public void orphan() throws DataException {
// Revert name
// Un-buy name
Name name = new Name(this.repository, this.buyNameTransactionData.getName());
name.unbuy(this.buyNameTransactionData);
// Save this transaction, with removed "name reference"
// Save this transaction, with previous "name reference"
this.repository.getTransactionRepository().save(this.buyNameTransactionData);
}

View File

@ -6,7 +6,6 @@ import java.util.List;
import org.qortal.account.Account;
import org.qortal.asset.Asset;
import org.qortal.block.BlockChain;
import org.qortal.crypto.Crypto;
import org.qortal.data.transaction.RegisterNameTransactionData;
import org.qortal.data.transaction.TransactionData;
import org.qortal.naming.Name;
@ -32,7 +31,7 @@ public class RegisterNameTransaction extends Transaction {
@Override
public List<String> getRecipientAddresses() throws DataException {
return Collections.singletonList(this.registerNameTransactionData.getOwner());
return Collections.emptyList();
}
// Navigation
@ -46,23 +45,20 @@ public class RegisterNameTransaction extends Transaction {
@Override
public ValidationResult isValid() throws DataException {
Account registrant = getRegistrant();
// Check owner address is valid
if (!Crypto.isValidAddress(this.registerNameTransactionData.getOwner()))
return ValidationResult.INVALID_ADDRESS;
String name = this.registerNameTransactionData.getName();
// Check name size bounds
int nameLength = Utf8.encodedLength(this.registerNameTransactionData.getName());
if (nameLength < 1 || nameLength > Name.MAX_NAME_SIZE)
int nameLength = Utf8.encodedLength(name);
if (nameLength < Name.MIN_NAME_SIZE || nameLength > Name.MAX_NAME_SIZE)
return ValidationResult.INVALID_NAME_LENGTH;
// Check data size bounds
int dataLength = Utf8.encodedLength(this.registerNameTransactionData.getData());
if (dataLength < 1 || dataLength > Name.MAX_DATA_SIZE)
if (dataLength > Name.MAX_DATA_SIZE)
return ValidationResult.INVALID_DATA_LENGTH;
// Check name is lowercase
if (!this.registerNameTransactionData.getName().equals(this.registerNameTransactionData.getName().toLowerCase()))
if (!name.equals(name.toLowerCase()))
return ValidationResult.NAME_NOT_LOWER_CASE;
// Check registrant has enough funds
@ -78,10 +74,9 @@ public class RegisterNameTransaction extends Transaction {
if (this.repository.getNameRepository().nameExists(this.registerNameTransactionData.getName()))
return ValidationResult.NAME_ALREADY_REGISTERED;
Account registrant = getRegistrant();
// If accounts are only allowed one registered name then check for this
if (BlockChain.getInstance().oneNamePerAccount() && !this.repository.getNameRepository().getNamesByOwner(registrant.getAddress()).isEmpty())
if (BlockChain.getInstance().oneNamePerAccount()
&& !this.repository.getNameRepository().getNamesByOwner(getRegistrant().getAddress()).isEmpty())
return ValidationResult.MULTIPLE_NAMES_FORBIDDEN;
return ValidationResult.OK;

View File

@ -5,7 +5,6 @@ import java.util.List;
import org.qortal.account.Account;
import org.qortal.asset.Asset;
import org.qortal.crypto.Crypto;
import org.qortal.data.naming.NameData;
import org.qortal.data.transaction.TransactionData;
import org.qortal.data.transaction.UpdateNameTransactionData;
@ -32,7 +31,7 @@ public class UpdateNameTransaction extends Transaction {
@Override
public List<String> getRecipientAddresses() throws DataException {
return Collections.singletonList(this.updateNameTransactionData.getNewOwner());
return Collections.emptyList();
}
// Navigation
@ -41,30 +40,17 @@ public class UpdateNameTransaction extends Transaction {
return this.getCreator();
}
public Account getNewOwner() {
return new Account(this.repository, this.updateNameTransactionData.getNewOwner());
}
// Processing
@Override
public ValidationResult isValid() throws DataException {
String name = this.updateNameTransactionData.getName();
// Check new owner address is valid
if (!Crypto.isValidAddress(this.updateNameTransactionData.getNewOwner()))
return ValidationResult.INVALID_ADDRESS;
// Check name size bounds
int nameLength = Utf8.encodedLength(name);
if (nameLength < 1 || nameLength > Name.MAX_NAME_SIZE)
if (nameLength < Name.MIN_NAME_SIZE || nameLength > Name.MAX_NAME_SIZE)
return ValidationResult.INVALID_NAME_LENGTH;
// Check new data size bounds
int newDataLength = Utf8.encodedLength(this.updateNameTransactionData.getNewData());
if (newDataLength < 1 || newDataLength > Name.MAX_DATA_SIZE)
return ValidationResult.INVALID_DATA_LENGTH;
// Check name is lowercase
if (!name.equals(name.toLowerCase()))
return ValidationResult.NAME_NOT_LOWER_CASE;
@ -79,6 +65,24 @@ public class UpdateNameTransaction extends Transaction {
if (nameData.getCreationGroupId() != this.updateNameTransactionData.getTxGroupId())
return ValidationResult.TX_GROUP_ID_MISMATCH;
// Check new name (0 length means don't update name)
String newName = this.updateNameTransactionData.getNewName();
int newNameLength = Utf8.encodedLength(newName);
if (newNameLength != 0) {
// Check new name size bounds
if (newNameLength < Name.MIN_NAME_SIZE || newNameLength > Name.MAX_NAME_SIZE)
return ValidationResult.INVALID_NAME_LENGTH;
// Check new name is lowercase
if (!newName.equals(newName.toLowerCase()))
return ValidationResult.NAME_NOT_LOWER_CASE;
}
// Check new data size bounds (0 length means don't update data)
int newDataLength = Utf8.encodedLength(this.updateNameTransactionData.getNewData());
if (newDataLength > Name.MAX_DATA_SIZE)
return ValidationResult.INVALID_DATA_LENGTH;
Account owner = getOwner();
// Check owner has enough funds
@ -92,6 +96,10 @@ public class UpdateNameTransaction extends Transaction {
public ValidationResult isProcessable() throws DataException {
NameData nameData = this.repository.getNameRepository().fromName(this.updateNameTransactionData.getName());
// Check name still exists
if (nameData == null)
return ValidationResult.NAME_DOES_NOT_EXIST;
// Check name isn't currently for sale
if (nameData.getIsForSale())
return ValidationResult.NAME_ALREADY_FOR_SALE;
@ -102,6 +110,10 @@ public class UpdateNameTransaction extends Transaction {
if (!owner.getAddress().equals(nameData.getOwner()))
return ValidationResult.INVALID_NAME_OWNER;
// Check new name isn't already taken
if (this.repository.getNameRepository().nameExists(this.updateNameTransactionData.getNewName()))
return ValidationResult.NAME_ALREADY_REGISTERED;
return ValidationResult.OK;
}
@ -111,7 +123,7 @@ public class UpdateNameTransaction extends Transaction {
Name name = new Name(this.repository, this.updateNameTransactionData.getName());
name.update(this.updateNameTransactionData);
// Save this transaction, now with updated "name reference" to previous transaction that updated name
// Save this transaction, now with updated "name reference" to previous transaction that changed name
this.repository.getTransactionRepository().save(this.updateNameTransactionData);
}
@ -121,7 +133,7 @@ public class UpdateNameTransaction extends Transaction {
Name name = new Name(this.repository, this.updateNameTransactionData.getName());
name.revert(this.updateNameTransactionData);
// Save this transaction, now with removed "name reference"
// Save this transaction, with previous "name reference"
this.repository.getTransactionRepository().save(this.updateNameTransactionData);
}

View File

@ -33,7 +33,6 @@ public class RegisterNameTransactionTransformer extends TransactionTransformer {
layout.add("transaction's groupID", TransformationType.INT);
layout.add("reference", TransformationType.SIGNATURE);
layout.add("name registrant's public key", TransformationType.PUBLIC_KEY);
layout.add("name owner", TransformationType.ADDRESS);
layout.add("name length", TransformationType.INT);
layout.add("name", TransformationType.STRING);
layout.add("data length", TransformationType.INT);
@ -52,8 +51,6 @@ public class RegisterNameTransactionTransformer extends TransactionTransformer {
byte[] registrantPublicKey = Serialization.deserializePublicKey(byteBuffer);
String owner = Serialization.deserializeAddress(byteBuffer);
String name = Serialization.deserializeSizedString(byteBuffer, Name.MAX_NAME_SIZE);
String data = Serialization.deserializeSizedString(byteBuffer, Name.MAX_DATA_SIZE);
@ -65,7 +62,7 @@ public class RegisterNameTransactionTransformer extends TransactionTransformer {
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, registrantPublicKey, fee, signature);
return new RegisterNameTransactionData(baseTransactionData, owner, name, data);
return new RegisterNameTransactionData(baseTransactionData, name, data);
}
public static int getDataLength(TransactionData transactionData) throws TransformationException {
@ -83,8 +80,6 @@ public class RegisterNameTransactionTransformer extends TransactionTransformer {
transformCommonBytes(transactionData, bytes);
Serialization.serializeAddress(bytes, registerNameTransactionData.getOwner());
Serialization.serializeSizedString(bytes, registerNameTransactionData.getName());
Serialization.serializeSizedString(bytes, registerNameTransactionData.getData());

View File

@ -18,11 +18,11 @@ import com.google.common.primitives.Longs;
public class UpdateNameTransactionTransformer extends TransactionTransformer {
// Property lengths
private static final int OWNER_LENGTH = ADDRESS_LENGTH;
private static final int NAME_SIZE_LENGTH = INT_LENGTH;
private static final int DATA_SIZE_LENGTH = INT_LENGTH;
private static final int NEW_NAME_SIZE_LENGTH = INT_LENGTH;
private static final int NEW_DATA_SIZE_LENGTH = INT_LENGTH;
private static final int EXTRAS_LENGTH = OWNER_LENGTH + NAME_SIZE_LENGTH + DATA_SIZE_LENGTH;
private static final int EXTRAS_LENGTH = NAME_SIZE_LENGTH + NEW_NAME_SIZE_LENGTH + NEW_DATA_SIZE_LENGTH;
protected static final TransactionLayout layout;
@ -33,10 +33,11 @@ public class UpdateNameTransactionTransformer extends TransactionTransformer {
layout.add("transaction's groupID", TransformationType.INT);
layout.add("reference", TransformationType.SIGNATURE);
layout.add("name owner's public key", TransformationType.PUBLIC_KEY);
layout.add("name's new owner", TransformationType.ADDRESS);
layout.add("name length", TransformationType.INT);
layout.add("name", TransformationType.STRING);
layout.add("new data length", TransformationType.INT);
layout.add("new name's length (0 for no change)", TransformationType.INT);
layout.add("new name", TransformationType.STRING);
layout.add("new data length (0 for no change)", TransformationType.INT);
layout.add("new data", TransformationType.STRING);
layout.add("fee", TransformationType.AMOUNT);
layout.add("signature", TransformationType.SIGNATURE);
@ -52,10 +53,10 @@ public class UpdateNameTransactionTransformer extends TransactionTransformer {
byte[] ownerPublicKey = Serialization.deserializePublicKey(byteBuffer);
String newOwner = Serialization.deserializeAddress(byteBuffer);
String name = Serialization.deserializeSizedString(byteBuffer, Name.MAX_NAME_SIZE);
String newName = Serialization.deserializeSizedString(byteBuffer, Name.MAX_NAME_SIZE);
String newData = Serialization.deserializeSizedString(byteBuffer, Name.MAX_DATA_SIZE);
long fee = byteBuffer.getLong();
@ -65,13 +66,14 @@ public class UpdateNameTransactionTransformer extends TransactionTransformer {
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, txGroupId, reference, ownerPublicKey, fee, signature);
return new UpdateNameTransactionData(baseTransactionData, newOwner, name, newData);
return new UpdateNameTransactionData(baseTransactionData, name, newName, newData);
}
public static int getDataLength(TransactionData transactionData) throws TransformationException {
UpdateNameTransactionData updateNameTransactionData = (UpdateNameTransactionData) transactionData;
return getBaseLength(transactionData) + EXTRAS_LENGTH + Utf8.encodedLength(updateNameTransactionData.getName())
+ Utf8.encodedLength(updateNameTransactionData.getNewName())
+ Utf8.encodedLength(updateNameTransactionData.getNewData());
}
@ -83,10 +85,10 @@ public class UpdateNameTransactionTransformer extends TransactionTransformer {
transformCommonBytes(transactionData, bytes);
Serialization.serializeAddress(bytes, updateNameTransactionData.getNewOwner());
Serialization.serializeSizedString(bytes, updateNameTransactionData.getName());
Serialization.serializeSizedString(bytes, updateNameTransactionData.getNewName());
Serialization.serializeSizedString(bytes, updateNameTransactionData.getNewData());
bytes.write(Longs.toByteArray(updateNameTransactionData.getFee()));

View File

@ -46,7 +46,7 @@ public class NamesApiTests extends ApiCommon {
PrivateKeyAccount alice = Common.getTestAccount(repository, "alice");
String name = "test-name";
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), alice.getAddress(), name, "{}");
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "{}");
TransactionUtils.signAndMint(repository, transactionData, alice);
assertNotNull(this.namesResource.getNamesByAddress(alice.getAddress(), null, null, null));
@ -61,7 +61,7 @@ public class NamesApiTests extends ApiCommon {
PrivateKeyAccount alice = Common.getTestAccount(repository, "alice");
String name = "test-name";
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), alice.getAddress(), name, "{}");
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "{}");
TransactionUtils.signAndMint(repository, transactionData, alice);
assertNotNull(this.namesResource.getName(name));
@ -76,7 +76,7 @@ public class NamesApiTests extends ApiCommon {
String name = "test-name";
long price = 1_23456789L;
TransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), alice.getAddress(), name, "{}");
TransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "{}");
TransactionUtils.signAndMint(repository, transactionData, alice);
// Sell-name

View File

@ -9,14 +9,13 @@ import org.qortal.repository.Repository;
public class RegisterNameTestTransaction extends TestTransaction {
public static TransactionData randomTransaction(Repository repository, PrivateKeyAccount account, boolean wantValid) throws DataException {
String owner = account.getAddress();
String name = "test name";
if (!wantValid)
name += " " + random.nextInt(1_000_000);
String data = "{ \"key\": \"value\" }";
return new RegisterNameTransactionData(generateBase(account), owner, name, data);
return new RegisterNameTransactionData(generateBase(account), name, data);
}
}

View File

@ -61,7 +61,7 @@ public class BuySellTests extends Common {
@Test
public void testRegisterName() throws DataException {
// Register-name
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), alice.getAddress(), name, "{}");
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "{}");
TransactionUtils.signAndMint(repository, transactionData, alice);
String name = transactionData.getName();

View File

@ -29,7 +29,7 @@ public class MiscTests extends Common {
PrivateKeyAccount alice = Common.getTestAccount(repository, "alice");
String name = "test-name";
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), alice.getAddress(), name, "{}");
RegisterNameTransactionData transactionData = new RegisterNameTransactionData(TestTransaction.generateBase(alice), name, "{}");
TransactionUtils.signAndMint(repository, transactionData, alice);
List<String> recentNames = repository.getNameRepository().getRecentNames(0L);