diff --git a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java index 4d20f3cd..9a11a820 100644 --- a/src/main/java/org/qortal/transaction/ArbitraryTransaction.java +++ b/src/main/java/org/qortal/transaction/ArbitraryTransaction.java @@ -90,7 +90,8 @@ public class ArbitraryTransaction extends Transaction { // Disable reference checking after feature trigger timestamp if (this.arbitraryTransactionData.getTimestamp() >= BlockChain.getInstance().getDisableReferenceTimestamp()) { - return true; + // Allow any non-null value + return this.arbitraryTransactionData.getReference() != null; } if (this.arbitraryTransactionData.getReference() == null) { diff --git a/src/main/java/org/qortal/transaction/AtTransaction.java b/src/main/java/org/qortal/transaction/AtTransaction.java index d278a909..be0388a1 100644 --- a/src/main/java/org/qortal/transaction/AtTransaction.java +++ b/src/main/java/org/qortal/transaction/AtTransaction.java @@ -78,7 +78,8 @@ public class AtTransaction extends Transaction { public boolean hasValidReference() throws DataException { // Disable reference checking after feature trigger timestamp if (this.atTransactionData.getTimestamp() >= BlockChain.getInstance().getDisableReferenceTimestamp()) { - return true; + // Allow any non-null value + return this.atTransactionData.getReference() != null; } // Check reference is correct, using AT account, not transaction creator which is null account diff --git a/src/main/java/org/qortal/transaction/MessageTransaction.java b/src/main/java/org/qortal/transaction/MessageTransaction.java index 3a337e96..4540bea6 100644 --- a/src/main/java/org/qortal/transaction/MessageTransaction.java +++ b/src/main/java/org/qortal/transaction/MessageTransaction.java @@ -167,7 +167,8 @@ public class MessageTransaction extends Transaction { // Disable reference checking after feature trigger timestamp if (this.messageTransactionData.getTimestamp() >= BlockChain.getInstance().getDisableReferenceTimestamp()) { - return true; + // Allow any non-null value + return this.messageTransactionData.getReference() != null; } if (this.messageTransactionData.getReference() == null) diff --git a/src/main/java/org/qortal/transaction/Transaction.java b/src/main/java/org/qortal/transaction/Transaction.java index 60059163..9f56af6b 100644 --- a/src/main/java/org/qortal/transaction/Transaction.java +++ b/src/main/java/org/qortal/transaction/Transaction.java @@ -907,7 +907,8 @@ public abstract class Transaction { public boolean hasValidReference() throws DataException { // Disable reference checking after feature trigger timestamp if (this.transactionData.getTimestamp() >= BlockChain.getInstance().getDisableReferenceTimestamp()) { - return true; + // Allow any non-null value + return this.transactionData.getReference() != null; } Account creator = getCreator(); diff --git a/src/test/java/org/qortal/test/TransactionReferenceTests.java b/src/test/java/org/qortal/test/TransactionReferenceTests.java index a3b24e69..41124649 100644 --- a/src/test/java/org/qortal/test/TransactionReferenceTests.java +++ b/src/test/java/org/qortal/test/TransactionReferenceTests.java @@ -80,4 +80,30 @@ public class TransactionReferenceTests extends Common { } } + @Test + public void testNullReferenceAfterFeatureTrigger() throws DataException { + Common.useSettings("test-settings-v2-disable-reference.json"); + Random random = new Random(); + + try (final Repository repository = RepositoryManager.getRepository()) { + PrivateKeyAccount alice = Common.getTestAccount(repository, "alice"); + + byte[] randomPrivateKey = new byte[32]; + random.nextBytes(randomPrivateKey); + PrivateKeyAccount recipient = new PrivateKeyAccount(repository, randomPrivateKey); + + // Create payment transaction data + TransactionData paymentTransactionData = new PaymentTransactionData(TestTransaction.generateBase(alice), recipient.getAddress(), 100000L); + + // Set null reference + paymentTransactionData.setReference(null); + + Transaction paymentTransaction = Transaction.fromData(repository, paymentTransactionData); + + // Transaction should be invalid, as we require a non-null reference + Transaction.ValidationResult validationResult = paymentTransaction.isValidUnconfirmed(); + assertEquals(Transaction.ValidationResult.INVALID_REFERENCE, validationResult); + } + } + }