From 911ff3fc1ba510f0f38e7ef2db7e9415a9980cc1 Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Tue, 9 Sep 2025 14:35:45 +0400 Subject: [PATCH 1/8] Test for double spend --- .../unicitylabs/sdk/TestAggregatorClient.java | 2 +- .../FunctionalNametagDoubleSpendTest.java | 121 ++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/unicitylabs/sdk/functional/FunctionalNametagDoubleSpendTest.java diff --git a/src/test/java/org/unicitylabs/sdk/TestAggregatorClient.java b/src/test/java/org/unicitylabs/sdk/TestAggregatorClient.java index 6c3f9f8..f59b780 100644 --- a/src/test/java/org/unicitylabs/sdk/TestAggregatorClient.java +++ b/src/test/java/org/unicitylabs/sdk/TestAggregatorClient.java @@ -39,7 +39,7 @@ public CompletableFuture submitCommitment(RequestId re new SubmitCommitmentResponse(SubmitCommitmentStatus.SUCCESS) ); } catch (Exception e) { - throw new RuntimeException(e); + throw new RuntimeException("Aggregator commitment failed", e); } } diff --git a/src/test/java/org/unicitylabs/sdk/functional/FunctionalNametagDoubleSpendTest.java b/src/test/java/org/unicitylabs/sdk/functional/FunctionalNametagDoubleSpendTest.java new file mode 100644 index 0000000..2a390fa --- /dev/null +++ b/src/test/java/org/unicitylabs/sdk/functional/FunctionalNametagDoubleSpendTest.java @@ -0,0 +1,121 @@ +package org.unicitylabs.sdk.functional; + +import static org.unicitylabs.sdk.utils.TestUtils.randomBytes; + +import java.nio.charset.StandardCharsets; +import java.util.List; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.unicitylabs.sdk.StateTransitionClient; +import org.unicitylabs.sdk.TestAggregatorClient; +import org.unicitylabs.sdk.address.Address; +import org.unicitylabs.sdk.address.DirectAddress; +import org.unicitylabs.sdk.address.ProxyAddress; +import org.unicitylabs.sdk.api.SubmitCommitmentResponse; +import org.unicitylabs.sdk.api.SubmitCommitmentStatus; +import org.unicitylabs.sdk.common.BaseEscrowSwapTest; +import org.unicitylabs.sdk.hash.DataHasher; +import org.unicitylabs.sdk.hash.HashAlgorithm; +import org.unicitylabs.sdk.mtree.BranchExistsException; +import org.unicitylabs.sdk.predicate.MaskedPredicate; +import org.unicitylabs.sdk.predicate.Predicate; +import org.unicitylabs.sdk.predicate.UnmaskedPredicate; +import org.unicitylabs.sdk.predicate.UnmaskedPredicateReference; +import org.unicitylabs.sdk.serializer.UnicityObjectMapper; +import org.unicitylabs.sdk.signing.SigningService; +import org.unicitylabs.sdk.token.Token; +import org.unicitylabs.sdk.token.TokenId; +import org.unicitylabs.sdk.token.TokenState; +import org.unicitylabs.sdk.token.TokenType; +import org.unicitylabs.sdk.transaction.Transaction; +import org.unicitylabs.sdk.transaction.TransferCommitment; +import org.unicitylabs.sdk.transaction.TransferTransactionData; +import org.unicitylabs.sdk.util.HexConverter; +import org.unicitylabs.sdk.util.InclusionProofUtils; +import org.unicitylabs.sdk.utils.TokenUtils; + +public class FunctionalNametagDoubleSpendTest { + protected StateTransitionClient client = new StateTransitionClient(new TestAggregatorClient()); + private final byte[] BOB_SECRET = "BOB_SECRET".getBytes(StandardCharsets.UTF_8); + + private String[] transferToken(Token token, byte[] secret, Address address) throws Exception { + TransferCommitment commitment = TransferCommitment.create( + token, + address, + randomBytes(32), + null, + null, + SigningService.createFromSecret(secret, token.getState().getUnlockPredicate().getNonce()) + ); + + SubmitCommitmentResponse response = this.client.submitCommitment(token, commitment).get(); + if (response.getStatus() != SubmitCommitmentStatus.SUCCESS) { + throw new RuntimeException("Failed to submit transfer commitment: " + response); + } + + return new String[]{ + UnicityObjectMapper.JSON.writeValueAsString(token), + UnicityObjectMapper.JSON.writeValueAsString(commitment.toTransaction(token, + InclusionProofUtils.waitInclusionProof(client, commitment).get())) + }; + } + + private Token mintToken(byte[] secret) throws Exception { + return TokenUtils.mintToken( + this.client, + secret, + new TokenId(randomBytes(32)), + new TokenType(HexConverter.decode( + "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509")), + randomBytes(32), + null, + randomBytes(32), + randomBytes(32), + null + ); + } + + private Token receiveToken(String[] tokenInfo, byte[] secret) throws Exception { + Token token = UnicityObjectMapper.JSON.readValue(tokenInfo[0], Token.class); + Transaction transaction = UnicityObjectMapper.JSON.readValue( + tokenInfo[1], + UnicityObjectMapper.JSON.getTypeFactory() + .constructParametricType(Transaction.class, TransferTransactionData.class)); + + TokenState state = new TokenState( + UnmaskedPredicate.create( + SigningService.createFromSecret(secret, null), + HashAlgorithm.SHA256, + transaction.getData().getSalt() + ), + null + ); + + return this.client.finalizeTransaction( + token, + state, + transaction, + List.of() + ); + } + + @Test + void testDoubleSpend() throws Exception { + Token token = mintToken(BOB_SECRET); + + UnmaskedPredicateReference reference = UnmaskedPredicateReference.create( + token.getType(), + SigningService.createFromSecret(BOB_SECRET, null), + HashAlgorithm.SHA256 + ); + + Assertions.assertTrue(receiveToken(transferToken(token, BOB_SECRET, reference.toAddress()), BOB_SECRET).verify().isSuccessful()); + RuntimeException ex = Assertions.assertThrows( + RuntimeException.class, + () -> receiveToken(transferToken(token, BOB_SECRET, reference.toAddress()), + BOB_SECRET).verify().isSuccessful() + ); + + Assertions.assertInstanceOf(BranchExistsException.class, ex.getCause()); + } +} From fd8e9a7dd576a1bfb82f4780d0531adb45996c78 Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Tue, 9 Sep 2025 20:49:14 +0400 Subject: [PATCH 2/8] Temporary solution for verifying unmaskedPredicate --- .../sdk/predicate/BurnPredicate.java | 9 +- .../sdk/predicate/DefaultPredicate.java | 17 ++- .../unicitylabs/sdk/predicate/Predicate.java | 8 +- .../sdk/predicate/UnmaskedPredicate.java | 24 ++++ .../predicate/UnmaskedPredicateReference.java | 1 + .../java/org/unicitylabs/sdk/token/Token.java | 28 +++-- .../unicitylabs/sdk/e2e/CommonTestFlow.java | 108 ++++++++++-------- .../functional/FunctionalCommonFlowTest.java | 22 ++++ ...onalUnsignedPredicateDoubleSpendTest.java} | 8 +- 9 files changed, 150 insertions(+), 75 deletions(-) create mode 100644 src/test/java/org/unicitylabs/sdk/functional/FunctionalCommonFlowTest.java rename src/test/java/org/unicitylabs/sdk/functional/{FunctionalNametagDoubleSpendTest.java => FunctionalUnsignedPredicateDoubleSpendTest.java} (92%) diff --git a/src/main/java/org/unicitylabs/sdk/predicate/BurnPredicate.java b/src/main/java/org/unicitylabs/sdk/predicate/BurnPredicate.java index 8367963..19b3141 100644 --- a/src/main/java/org/unicitylabs/sdk/predicate/BurnPredicate.java +++ b/src/main/java/org/unicitylabs/sdk/predicate/BurnPredicate.java @@ -2,11 +2,14 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.ArrayNode; +import java.util.List; +import java.util.ListIterator; import org.unicitylabs.sdk.hash.DataHash; import org.unicitylabs.sdk.hash.DataHasher; import org.unicitylabs.sdk.hash.HashAlgorithm; import org.unicitylabs.sdk.serializer.UnicityObjectMapper; import org.unicitylabs.sdk.serializer.cbor.CborSerializationException; +import org.unicitylabs.sdk.token.Token; import org.unicitylabs.sdk.token.TokenId; import org.unicitylabs.sdk.token.TokenType; import org.unicitylabs.sdk.transaction.Transaction; @@ -47,8 +50,10 @@ public boolean isOwner(byte[] publicKey) { } @Override - public boolean verify(Transaction transaction, TokenId tokenId, - TokenType tokenType) { + public boolean verify( + List> transactions, + Token token + ) { return false; } diff --git a/src/main/java/org/unicitylabs/sdk/predicate/DefaultPredicate.java b/src/main/java/org/unicitylabs/sdk/predicate/DefaultPredicate.java index afaa01b..86824e3 100644 --- a/src/main/java/org/unicitylabs/sdk/predicate/DefaultPredicate.java +++ b/src/main/java/org/unicitylabs/sdk/predicate/DefaultPredicate.java @@ -2,20 +2,22 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.ArrayNode; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; import org.unicitylabs.sdk.api.Authenticator; import org.unicitylabs.sdk.api.RequestId; import org.unicitylabs.sdk.hash.DataHash; import org.unicitylabs.sdk.hash.DataHasher; import org.unicitylabs.sdk.hash.HashAlgorithm; import org.unicitylabs.sdk.serializer.UnicityObjectMapper; +import org.unicitylabs.sdk.token.Token; import org.unicitylabs.sdk.token.TokenId; import org.unicitylabs.sdk.token.TokenType; import org.unicitylabs.sdk.transaction.InclusionProofVerificationStatus; import org.unicitylabs.sdk.transaction.Transaction; import org.unicitylabs.sdk.transaction.TransferTransactionData; import org.unicitylabs.sdk.util.HexConverter; -import java.util.Arrays; -import java.util.Objects; /** * Base class for unmasked and masked predicates @@ -91,8 +93,11 @@ public boolean isOwner(byte[] publicKey) { } @Override - public boolean verify(Transaction transaction, TokenId tokenId, - TokenType tokenType) { + public boolean verify( + List> transactions, + Token token) { + Transaction transaction = transactions.getLast(); + Authenticator authenticator = transaction.getInclusionProof().getAuthenticator().orElse(null); DataHash transactionHash = transaction.getInclusionProof().getTransactionHash().orElse(null); @@ -104,12 +109,12 @@ public boolean verify(Transaction transaction, TokenId return false; } - if (!authenticator.verify(transaction.getData().calculateHash(tokenId, tokenType))) { + if (!authenticator.verify(transaction.getData().calculateHash(token.getId(), token.getType()))) { return false; } RequestId requestId = RequestId.create(this.publicKey, - transaction.getData().getSourceState().calculateHash(tokenId, tokenType)); + transaction.getData().getSourceState().calculateHash(token.getId(), token.getType())); return transaction.getInclusionProof().verify(requestId) == InclusionProofVerificationStatus.OK; } diff --git a/src/main/java/org/unicitylabs/sdk/predicate/Predicate.java b/src/main/java/org/unicitylabs/sdk/predicate/Predicate.java index d72df36..1aacdc9 100644 --- a/src/main/java/org/unicitylabs/sdk/predicate/Predicate.java +++ b/src/main/java/org/unicitylabs/sdk/predicate/Predicate.java @@ -1,6 +1,8 @@ package org.unicitylabs.sdk.predicate; +import java.util.List; import org.unicitylabs.sdk.hash.DataHash; +import org.unicitylabs.sdk.token.Token; import org.unicitylabs.sdk.token.TokenId; import org.unicitylabs.sdk.token.TokenType; import org.unicitylabs.sdk.transaction.Transaction; @@ -12,6 +14,8 @@ public interface Predicate { IPredicateReference getReference(TokenType tokenType); byte[] getNonce(); boolean isOwner(byte[] publicKey); - boolean verify(Transaction transaction, TokenId tokenId, - TokenType tokenType); + boolean verify( + List> transactions, + Token token + ); } \ No newline at end of file diff --git a/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicate.java b/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicate.java index cbb1e6b..19b34f2 100644 --- a/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicate.java +++ b/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicate.java @@ -3,6 +3,8 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.ArrayNode; +import java.util.List; +import java.util.ListIterator; import org.unicitylabs.sdk.hash.DataHash; import org.unicitylabs.sdk.hash.DataHasher; import org.unicitylabs.sdk.hash.HashAlgorithm; @@ -10,8 +12,12 @@ import org.unicitylabs.sdk.serializer.cbor.CborSerializationException; import org.unicitylabs.sdk.signing.Signature; import org.unicitylabs.sdk.signing.SigningService; +import org.unicitylabs.sdk.token.Token; import org.unicitylabs.sdk.token.TokenId; import org.unicitylabs.sdk.token.TokenType; +import org.unicitylabs.sdk.transaction.Transaction; +import org.unicitylabs.sdk.transaction.TransferTransactionData; +import org.unicitylabs.sdk.util.HexConverter; public class UnmaskedPredicate extends DefaultPredicate { @@ -38,6 +44,24 @@ public static UnmaskedPredicate create( nonce.getBytes()); } + @Override + public boolean verify( + List> transactions, + Token token + ) { + return super.verify(transactions, token) && SigningService.verifyWithPublicKey( + new DataHasher(HashAlgorithm.SHA256) + .update( + transactions.size() > 1 + ? transactions.get(transactions.size() - 2).getData().getSalt() + : token.getGenesis().getData().getSalt() + ) + .digest(), + this.getNonce(), + this.getPublicKey() + ); + } + @Override public DataHash calculateHash(TokenId tokenId, TokenType tokenType) { IPredicateReference reference = this.getReference(tokenType); diff --git a/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicateReference.java b/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicateReference.java index ae85e9e..268615c 100644 --- a/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicateReference.java +++ b/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicateReference.java @@ -10,6 +10,7 @@ import org.unicitylabs.sdk.serializer.cbor.CborSerializationException; import org.unicitylabs.sdk.signing.SigningService; import org.unicitylabs.sdk.token.TokenType; +import org.unicitylabs.sdk.util.HexConverter; public class UnmaskedPredicateReference implements IPredicateReference { diff --git a/src/main/java/org/unicitylabs/sdk/token/Token.java b/src/main/java/org/unicitylabs/sdk/token/Token.java index c44faa5..43bd933 100644 --- a/src/main/java/org/unicitylabs/sdk/token/Token.java +++ b/src/main/java/org/unicitylabs/sdk/token/Token.java @@ -1,5 +1,7 @@ package org.unicitylabs.sdk.token; +import java.util.LinkedList; +import java.util.stream.Stream; import org.unicitylabs.sdk.address.Address; import org.unicitylabs.sdk.address.ProxyAddress; import org.unicitylabs.sdk.api.RequestId; @@ -31,8 +33,12 @@ public class Token> { private final List> transactions; private final List> nametags; - public Token(TokenState state, Transaction genesis, List> transactions, - List> nametags) { + public Token( + TokenState state, + Transaction genesis, + List> transactions, + List> nametags + ) { Objects.requireNonNull(state, "State cannot be null"); Objects.requireNonNull(genesis, "Genesis cannot be null"); Objects.requireNonNull(transactions, "Transactions list cannot be null"); @@ -97,8 +103,9 @@ public Token update( Objects.requireNonNull(transaction, "Transaction is null"); Objects.requireNonNull(transactionNametags, "Nametag tokens are null"); - if (!transaction.getData().getSourceState().getUnlockPredicate() - .verify(transaction, this.getId(), this.getType())) { + LinkedList> verificationTransactions = new LinkedList<>(this.transactions); + verificationTransactions.add(transaction); + if (!transaction.getData().getSourceState().getUnlockPredicate().verify(verificationTransactions, this)) { throw new RuntimeException("Predicate verification failed"); } @@ -130,15 +137,17 @@ public VerificationResult verify() { ); Transaction> previousTransaction = this.genesis; - for (Transaction transaction : this.transactions) { + for (int i = 0; i < this.transactions.size(); i++) { + Transaction transaction = this.transactions.get(i); Address recipient = previousTransaction.getData().getRecipient(); + results.add( VerificationResult.fromChildren( "Transaction verification", List.of( this.verifyTransaction( - transaction, + this.transactions.subList(0, i + 1), previousTransaction.getData().getDataHash().orElse(null), recipient ) @@ -189,8 +198,8 @@ public VerificationResult verify() { } private VerificationResult verifyTransaction( - Transaction transaction, DataHash dataHash, Address recipient) { - + List> transactions, DataHash dataHash, Address recipient) { + Transaction transaction = transactions.getLast(); for (Token nametag : transaction.getData().getNametags()) { if (!nametag.verify().isSuccessful()) { return VerificationResult.fail( @@ -212,8 +221,7 @@ private VerificationResult verifyTransaction( return VerificationResult.fail("data mismatch"); } - if (!transaction.getData().getSourceState().getUnlockPredicate() - .verify(transaction, this.getId(), this.getType())) { + if (!transaction.getData().getSourceState().getUnlockPredicate().verify(transactions, this)) { return VerificationResult.fail("predicate verification failed"); } diff --git a/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java b/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java index 5895c0f..0b8fbbc 100644 --- a/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java +++ b/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java @@ -36,6 +36,7 @@ import org.unicitylabs.sdk.transaction.TransferTransactionData; import org.unicitylabs.sdk.transaction.split.TokenSplitBuilder; import org.unicitylabs.sdk.transaction.split.TokenSplitBuilder.TokenSplit; +import org.unicitylabs.sdk.util.HexConverter; import org.unicitylabs.sdk.util.InclusionProofUtils; import org.unicitylabs.sdk.utils.TestTokenData; import java.math.BigInteger; @@ -210,9 +211,9 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti assertEquals(aliceToken.getType(), bobToken.getType()); // Transfer to Carol with UnmaskedPredicate - byte[] carolNonce = randomBytes(32); - SigningService carolSigningService = SigningService.createFromSecret(CAROL_SECRET, carolNonce); - DirectAddress carolAddress = UnmaskedPredicateReference.create(tokenType, carolSigningService, + DirectAddress carolAddress = UnmaskedPredicateReference.create( + tokenType, + SigningService.createFromSecret(CAROL_SECRET, null), HashAlgorithm.SHA256).toAddress(); // Bob transfers to Carol (no custom data) @@ -246,9 +247,9 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti // Carol creates UnmaskedPredicate and finalizes UnmaskedPredicate carolPredicate = UnmaskedPredicate.create( - carolSigningService, + SigningService.createFromSecret(CAROL_SECRET, null), HashAlgorithm.SHA256, - carolNonce + bobToCarolTransaction.getData().getSalt() ); Token carolToken = client.finalizeTransaction( @@ -261,11 +262,32 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti assertEquals(2, carolToken.getTransactions().size()); // Bob receives carol token with nametag - byte[] carolToBobNonce = randomBytes(32); - UnmaskedPredicate carolToBobPredicate = UnmaskedPredicate.create( - SigningService.createFromSecret(BOB_SECRET, carolToBobNonce), - HashAlgorithm.SHA256, - carolToBobNonce + TransferCommitment carolToBobTransferCommitment = TransferCommitment.create( + carolToken, + ProxyAddress.create(bobNameTag), + randomBytes(32), + null, + null, + SigningService.createFromSecret(CAROL_SECRET, null) + ); + SubmitCommitmentResponse carolToBobTransferSubmitResponse = client.submitCommitment( + carolToken, + carolToBobTransferCommitment + ).get(); + + if (carolToBobTransferSubmitResponse.getStatus() != SubmitCommitmentStatus.SUCCESS) { + throw new Exception(String.format("Failed to submit transaction commitment: %s", + carolToBobTransferSubmitResponse.getStatus())); + } + + InclusionProof carolToBobInclusionProof = InclusionProofUtils.waitInclusionProof( + client, + carolToBobTransferCommitment + ).get(); + + Transaction carolToBobTransaction = carolToBobTransferCommitment.toTransaction( + carolToken, + carolToBobInclusionProof ); byte[] bobNametagSecondUseNonce = randomBytes(32); @@ -275,7 +297,11 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti HashAlgorithm.SHA256, bobNametagSecondUseNonce ), - carolToBobPredicate.getReference(carolToken.getType()).toAddress() + UnmaskedPredicateReference.create( + carolToken.getType(), + SigningService.createFromSecret(BOB_SECRET, null), + HashAlgorithm.SHA256 + ).toAddress() ); TransferCommitment nametagSecondUseCommitment = TransferCommitment.create( @@ -285,14 +311,15 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti randomBytes(32), new DataHasher(HashAlgorithm.SHA256) .update( - nametagSecondUseTokenState.getData() - .orElseThrow( - () -> new RuntimeException("Invalid nametag, address data missing") - ) + nametagSecondUseTokenState.getAddress() + .getAddress().getBytes(StandardCharsets.UTF_8) ) .digest(), null, - SigningService.createFromSecret(BOB_SECRET, bobNametagNonce) + SigningService.createFromSecret( + BOB_SECRET, + bobNametagToken.getState().getUnlockPredicate().getNonce() + ) ); SubmitCommitmentResponse nametagSecondUseResponse = client.submitCommitment( bobNametagToken, @@ -307,41 +334,24 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti Token bobSecondUseNametag = client.finalizeTransaction( bobNametagToken, nametagSecondUseTokenState, - nametagSecondUseCommitment.toTransaction(bobNametagToken, - InclusionProofUtils.waitInclusionProof(client, nametagSecondUseCommitment).get()) - ); - - TransferCommitment carolToBobTransferCommitment = TransferCommitment.create( - carolToken, - ProxyAddress.create(bobNametagToken.getId()), - randomBytes(32), - null, - null, - carolSigningService + nametagSecondUseCommitment.toTransaction( + bobNametagToken, + InclusionProofUtils.waitInclusionProof(client, nametagSecondUseCommitment).get() + ) ); - SubmitCommitmentResponse carolToBobTransferSubmitResponse = client.submitCommitment( - carolToken, - carolToBobTransferCommitment - ).get(); - - if (carolToBobTransferSubmitResponse.getStatus() != SubmitCommitmentStatus.SUCCESS) { - throw new Exception(String.format("Failed to submit transaction commitment: %s", - carolToBobTransferSubmitResponse.getStatus())); - } - InclusionProof carolToBobInclusionProof = InclusionProofUtils.waitInclusionProof( - client, - carolToBobTransferCommitment - ).get(); - - Transaction carolToBobTransaction = carolToBobTransferCommitment.toTransaction( - carolToken, - carolToBobInclusionProof - ); + Assertions.assertTrue(bobSecondUseNametag.verify().isSuccessful()); Token carolToBobToken = client.finalizeTransaction( carolToken, - new TokenState(carolToBobPredicate, null), + new TokenState( + UnmaskedPredicate.create( + SigningService.createFromSecret(BOB_SECRET, null), + HashAlgorithm.SHA256, + carolToBobTransaction.getData().getSalt() + ), + null + ), carolToBobTransaction, List.of(bobSecondUseNametag) ); @@ -381,8 +391,10 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti ) .build(carolToBobToken); - TransferCommitment burnCommitment = split.createBurnCommitment(randomBytes(32), - SigningService.createFromSecret(BOB_SECRET, carolToBobNonce)); + TransferCommitment burnCommitment = split.createBurnCommitment( + randomBytes(32), + SigningService.createFromSecret(BOB_SECRET, null) + ); if (client.submitCommitment(carolToBobToken, burnCommitment).get().getStatus() != SubmitCommitmentStatus.SUCCESS) { diff --git a/src/test/java/org/unicitylabs/sdk/functional/FunctionalCommonFlowTest.java b/src/test/java/org/unicitylabs/sdk/functional/FunctionalCommonFlowTest.java new file mode 100644 index 0000000..dce9cbf --- /dev/null +++ b/src/test/java/org/unicitylabs/sdk/functional/FunctionalCommonFlowTest.java @@ -0,0 +1,22 @@ +package org.unicitylabs.sdk.functional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.unicitylabs.sdk.StateTransitionClient; +import org.unicitylabs.sdk.TestAggregatorClient; +import org.unicitylabs.sdk.e2e.CommonTestFlow; + +public class FunctionalCommonFlowTest { + + private StateTransitionClient client; + + @BeforeEach + void setUp() { + this.client = new StateTransitionClient(new TestAggregatorClient()); + } + + @Test + void testTransferFlow() throws Exception { + CommonTestFlow.testTransferFlow(this.client); + } +} \ No newline at end of file diff --git a/src/test/java/org/unicitylabs/sdk/functional/FunctionalNametagDoubleSpendTest.java b/src/test/java/org/unicitylabs/sdk/functional/FunctionalUnsignedPredicateDoubleSpendTest.java similarity index 92% rename from src/test/java/org/unicitylabs/sdk/functional/FunctionalNametagDoubleSpendTest.java rename to src/test/java/org/unicitylabs/sdk/functional/FunctionalUnsignedPredicateDoubleSpendTest.java index 2a390fa..28f7aa8 100644 --- a/src/test/java/org/unicitylabs/sdk/functional/FunctionalNametagDoubleSpendTest.java +++ b/src/test/java/org/unicitylabs/sdk/functional/FunctionalUnsignedPredicateDoubleSpendTest.java @@ -9,16 +9,10 @@ import org.unicitylabs.sdk.StateTransitionClient; import org.unicitylabs.sdk.TestAggregatorClient; import org.unicitylabs.sdk.address.Address; -import org.unicitylabs.sdk.address.DirectAddress; -import org.unicitylabs.sdk.address.ProxyAddress; import org.unicitylabs.sdk.api.SubmitCommitmentResponse; import org.unicitylabs.sdk.api.SubmitCommitmentStatus; -import org.unicitylabs.sdk.common.BaseEscrowSwapTest; -import org.unicitylabs.sdk.hash.DataHasher; import org.unicitylabs.sdk.hash.HashAlgorithm; import org.unicitylabs.sdk.mtree.BranchExistsException; -import org.unicitylabs.sdk.predicate.MaskedPredicate; -import org.unicitylabs.sdk.predicate.Predicate; import org.unicitylabs.sdk.predicate.UnmaskedPredicate; import org.unicitylabs.sdk.predicate.UnmaskedPredicateReference; import org.unicitylabs.sdk.serializer.UnicityObjectMapper; @@ -34,7 +28,7 @@ import org.unicitylabs.sdk.util.InclusionProofUtils; import org.unicitylabs.sdk.utils.TokenUtils; -public class FunctionalNametagDoubleSpendTest { +public class FunctionalUnsignedPredicateDoubleSpendTest { protected StateTransitionClient client = new StateTransitionClient(new TestAggregatorClient()); private final byte[] BOB_SECRET = "BOB_SECRET".getBytes(StandardCharsets.UTF_8); From 158232c08715b8ca04f8fb1d8225291e7bb973b5 Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Tue, 9 Sep 2025 20:52:20 +0400 Subject: [PATCH 3/8] Remove unused imports --- .../sdk/predicate/BurnPredicate.java | 5 ++-- .../sdk/predicate/UnmaskedPredicate.java | 2 -- .../predicate/UnmaskedPredicateReference.java | 1 - .../java/org/unicitylabs/sdk/token/Token.java | 13 +++++---- .../sdk/common/split/BaseTokenSplitTest.java | 14 +++++----- .../unicitylabs/sdk/e2e/CommonTestFlow.java | 27 +++++++++---------- 6 files changed, 27 insertions(+), 35 deletions(-) diff --git a/src/main/java/org/unicitylabs/sdk/predicate/BurnPredicate.java b/src/main/java/org/unicitylabs/sdk/predicate/BurnPredicate.java index 19b3141..416fa9a 100644 --- a/src/main/java/org/unicitylabs/sdk/predicate/BurnPredicate.java +++ b/src/main/java/org/unicitylabs/sdk/predicate/BurnPredicate.java @@ -2,8 +2,9 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.ArrayNode; +import java.util.Arrays; import java.util.List; -import java.util.ListIterator; +import java.util.Objects; import org.unicitylabs.sdk.hash.DataHash; import org.unicitylabs.sdk.hash.DataHasher; import org.unicitylabs.sdk.hash.HashAlgorithm; @@ -14,8 +15,6 @@ import org.unicitylabs.sdk.token.TokenType; import org.unicitylabs.sdk.transaction.Transaction; import org.unicitylabs.sdk.transaction.TransferTransactionData; -import java.util.Arrays; -import java.util.Objects; public class BurnPredicate implements Predicate { private final DataHash burnReason; diff --git a/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicate.java b/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicate.java index 19b34f2..07b7bd7 100644 --- a/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicate.java +++ b/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicate.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.node.ArrayNode; import java.util.List; -import java.util.ListIterator; import org.unicitylabs.sdk.hash.DataHash; import org.unicitylabs.sdk.hash.DataHasher; import org.unicitylabs.sdk.hash.HashAlgorithm; @@ -17,7 +16,6 @@ import org.unicitylabs.sdk.token.TokenType; import org.unicitylabs.sdk.transaction.Transaction; import org.unicitylabs.sdk.transaction.TransferTransactionData; -import org.unicitylabs.sdk.util.HexConverter; public class UnmaskedPredicate extends DefaultPredicate { diff --git a/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicateReference.java b/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicateReference.java index 268615c..ae85e9e 100644 --- a/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicateReference.java +++ b/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicateReference.java @@ -10,7 +10,6 @@ import org.unicitylabs.sdk.serializer.cbor.CborSerializationException; import org.unicitylabs.sdk.signing.SigningService; import org.unicitylabs.sdk.token.TokenType; -import org.unicitylabs.sdk.util.HexConverter; public class UnmaskedPredicateReference implements IPredicateReference { diff --git a/src/main/java/org/unicitylabs/sdk/token/Token.java b/src/main/java/org/unicitylabs/sdk/token/Token.java index 43bd933..9fa7f70 100644 --- a/src/main/java/org/unicitylabs/sdk/token/Token.java +++ b/src/main/java/org/unicitylabs/sdk/token/Token.java @@ -1,7 +1,11 @@ package org.unicitylabs.sdk.token; +import java.util.ArrayList; +import java.util.Arrays; import java.util.LinkedList; -import java.util.stream.Stream; +import java.util.List; +import java.util.Objects; +import java.util.Optional; import org.unicitylabs.sdk.address.Address; import org.unicitylabs.sdk.address.ProxyAddress; import org.unicitylabs.sdk.api.RequestId; @@ -12,17 +16,12 @@ import org.unicitylabs.sdk.token.fungible.TokenCoinData; import org.unicitylabs.sdk.transaction.InclusionProofVerificationStatus; import org.unicitylabs.sdk.transaction.MintCommitment; -import org.unicitylabs.sdk.transaction.MintTransactionState; import org.unicitylabs.sdk.transaction.MintTransactionData; +import org.unicitylabs.sdk.transaction.MintTransactionState; import org.unicitylabs.sdk.transaction.Transaction; import org.unicitylabs.sdk.transaction.TransactionData; import org.unicitylabs.sdk.transaction.TransferTransactionData; import org.unicitylabs.sdk.util.VerificationResult; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.Optional; public class Token> { diff --git a/src/test/java/org/unicitylabs/sdk/common/split/BaseTokenSplitTest.java b/src/test/java/org/unicitylabs/sdk/common/split/BaseTokenSplitTest.java index aa317d4..b0c5101 100644 --- a/src/test/java/org/unicitylabs/sdk/common/split/BaseTokenSplitTest.java +++ b/src/test/java/org/unicitylabs/sdk/common/split/BaseTokenSplitTest.java @@ -2,14 +2,18 @@ import static org.unicitylabs.sdk.utils.TestUtils.randomBytes; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; import java.util.UUID; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.unicitylabs.sdk.StateTransitionClient; import org.unicitylabs.sdk.address.Address; -import org.unicitylabs.sdk.address.DirectAddress; import org.unicitylabs.sdk.address.ProxyAddress; import org.unicitylabs.sdk.api.SubmitCommitmentResponse; import org.unicitylabs.sdk.api.SubmitCommitmentStatus; -import org.unicitylabs.sdk.hash.DataHash; import org.unicitylabs.sdk.hash.DataHasher; import org.unicitylabs.sdk.hash.HashAlgorithm; import org.unicitylabs.sdk.predicate.MaskedPredicate; @@ -28,12 +32,6 @@ import org.unicitylabs.sdk.transaction.split.TokenSplitBuilder.TokenSplit; import org.unicitylabs.sdk.util.InclusionProofUtils; import org.unicitylabs.sdk.utils.TokenUtils; -import java.math.BigInteger; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Map; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; public abstract class BaseTokenSplitTest { diff --git a/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java b/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java index 0b8fbbc..655ae6e 100644 --- a/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java +++ b/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java @@ -1,10 +1,18 @@ package org.unicitylabs.sdk.e2e; -import static org.unicitylabs.sdk.utils.TestUtils.randomBytes; -import static org.unicitylabs.sdk.utils.TestUtils.randomCoinData; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.unicitylabs.sdk.utils.TestUtils.randomBytes; +import static org.unicitylabs.sdk.utils.TestUtils.randomCoinData; +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; +import org.junit.jupiter.api.Assertions; import org.unicitylabs.sdk.StateTransitionClient; import org.unicitylabs.sdk.address.Address; import org.unicitylabs.sdk.address.DirectAddress; @@ -24,29 +32,20 @@ import org.unicitylabs.sdk.token.TokenState; import org.unicitylabs.sdk.token.TokenType; import org.unicitylabs.sdk.token.fungible.CoinId; -import org.unicitylabs.sdk.transaction.MintTransactionReason; -import org.unicitylabs.sdk.transaction.NametagMintTransactionData; -import org.unicitylabs.sdk.transaction.split.SplitMintReason; import org.unicitylabs.sdk.token.fungible.TokenCoinData; import org.unicitylabs.sdk.transaction.InclusionProof; import org.unicitylabs.sdk.transaction.MintCommitment; import org.unicitylabs.sdk.transaction.MintTransactionData; +import org.unicitylabs.sdk.transaction.MintTransactionReason; +import org.unicitylabs.sdk.transaction.NametagMintTransactionData; import org.unicitylabs.sdk.transaction.Transaction; import org.unicitylabs.sdk.transaction.TransferCommitment; import org.unicitylabs.sdk.transaction.TransferTransactionData; +import org.unicitylabs.sdk.transaction.split.SplitMintReason; import org.unicitylabs.sdk.transaction.split.TokenSplitBuilder; import org.unicitylabs.sdk.transaction.split.TokenSplitBuilder.TokenSplit; -import org.unicitylabs.sdk.util.HexConverter; import org.unicitylabs.sdk.util.InclusionProofUtils; import org.unicitylabs.sdk.utils.TestTokenData; -import java.math.BigInteger; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.UUID; -import org.junit.jupiter.api.Assertions; /** * Common test flows for token operations, matching TypeScript SDK's CommonTestFlow. From f1a2b6f993f12c495c208e4911b482fb7791e00e Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Tue, 9 Sep 2025 20:59:37 +0400 Subject: [PATCH 4/8] Fix android sdk errors --- .../org/unicitylabs/sdk/predicate/DefaultPredicate.java | 5 +++-- src/main/java/org/unicitylabs/sdk/token/Token.java | 8 +++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/unicitylabs/sdk/predicate/DefaultPredicate.java b/src/main/java/org/unicitylabs/sdk/predicate/DefaultPredicate.java index 86824e3..5ce857a 100644 --- a/src/main/java/org/unicitylabs/sdk/predicate/DefaultPredicate.java +++ b/src/main/java/org/unicitylabs/sdk/predicate/DefaultPredicate.java @@ -95,8 +95,9 @@ public boolean isOwner(byte[] publicKey) { @Override public boolean verify( List> transactions, - Token token) { - Transaction transaction = transactions.getLast(); + Token token + ) { + Transaction transaction = transactions.get(transactions.size() - 1); Authenticator authenticator = transaction.getInclusionProof().getAuthenticator().orElse(null); DataHash transactionHash = transaction.getInclusionProof().getTransactionHash().orElse(null); diff --git a/src/main/java/org/unicitylabs/sdk/token/Token.java b/src/main/java/org/unicitylabs/sdk/token/Token.java index 9fa7f70..78f7035 100644 --- a/src/main/java/org/unicitylabs/sdk/token/Token.java +++ b/src/main/java/org/unicitylabs/sdk/token/Token.java @@ -140,7 +140,6 @@ public VerificationResult verify() { Transaction transaction = this.transactions.get(i); Address recipient = previousTransaction.getData().getRecipient(); - results.add( VerificationResult.fromChildren( "Transaction verification", @@ -197,8 +196,11 @@ public VerificationResult verify() { } private VerificationResult verifyTransaction( - List> transactions, DataHash dataHash, Address recipient) { - Transaction transaction = transactions.getLast(); + List> transactions, + DataHash dataHash, + Address recipient + ) { + Transaction transaction = transactions.get(transactions.size() - 1); for (Token nametag : transaction.getData().getNametags()) { if (!nametag.verify().isSuccessful()) { return VerificationResult.fail( From 5d7417f701e4f7c1cdd4f062e325c826727bad45 Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Wed, 10 Sep 2025 15:44:07 +0400 Subject: [PATCH 5/8] #9 Move nametag target address to token immutable data and fix tests --- .../unicitylabs/sdk/address/ProxyAddress.java | 4 +- .../sdk/predicate/UnmaskedPredicate.java | 24 -- .../sdk/token/NameTagTokenState.java | 19 -- .../NametagMintTransactionData.java | 12 +- .../sdk/common/BaseEscrowSwapTest.java | 218 ++++++++---------- .../sdk/common/split/BaseTokenSplitTest.java | 73 ++---- .../unicitylabs/sdk/e2e/CommonTestFlow.java | 84 ++----- .../org/unicitylabs/sdk/token/TokenTest.java | 18 +- .../org/unicitylabs/sdk/utils/TokenUtils.java | 10 +- 9 files changed, 140 insertions(+), 322 deletions(-) delete mode 100644 src/main/java/org/unicitylabs/sdk/token/NameTagTokenState.java diff --git a/src/main/java/org/unicitylabs/sdk/address/ProxyAddress.java b/src/main/java/org/unicitylabs/sdk/address/ProxyAddress.java index 4ed42bd..c95de61 100644 --- a/src/main/java/org/unicitylabs/sdk/address/ProxyAddress.java +++ b/src/main/java/org/unicitylabs/sdk/address/ProxyAddress.java @@ -64,12 +64,12 @@ public static Address resolve(Address inputAddress, List> nametags) { Address targetAddress = inputAddress; while (targetAddress.getScheme() != AddressScheme.DIRECT) { Token nametag = nametagMap.get(targetAddress); - if (nametag == null || nametag.getState().getData().isEmpty()) { + if (nametag == null || nametag.getData().isEmpty()) { return null; } targetAddress = AddressFactory.createAddress( - new String(nametag.getState().getData().get(), StandardCharsets.UTF_8)); + new String(nametag.getData().get(), StandardCharsets.UTF_8)); } return targetAddress; diff --git a/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicate.java b/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicate.java index 07b7bd7..2d2f182 100644 --- a/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicate.java +++ b/src/main/java/org/unicitylabs/sdk/predicate/UnmaskedPredicate.java @@ -1,18 +1,12 @@ package org.unicitylabs.sdk.predicate; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.node.ArrayNode; import java.util.List; -import org.unicitylabs.sdk.hash.DataHash; import org.unicitylabs.sdk.hash.DataHasher; import org.unicitylabs.sdk.hash.HashAlgorithm; -import org.unicitylabs.sdk.serializer.UnicityObjectMapper; -import org.unicitylabs.sdk.serializer.cbor.CborSerializationException; import org.unicitylabs.sdk.signing.Signature; import org.unicitylabs.sdk.signing.SigningService; import org.unicitylabs.sdk.token.Token; -import org.unicitylabs.sdk.token.TokenId; import org.unicitylabs.sdk.token.TokenType; import org.unicitylabs.sdk.transaction.Transaction; import org.unicitylabs.sdk.transaction.TransferTransactionData; @@ -60,24 +54,6 @@ public boolean verify( ); } - @Override - public DataHash calculateHash(TokenId tokenId, TokenType tokenType) { - IPredicateReference reference = this.getReference(tokenType); - - ArrayNode node = UnicityObjectMapper.CBOR.createArrayNode(); - node.addPOJO(reference.getHash()); - node.addPOJO(tokenId); - node.addPOJO(this.getNonce()); - - try { - return new DataHasher(HashAlgorithm.SHA256) - .update(UnicityObjectMapper.CBOR.writeValueAsBytes(reference.getHash())) - .digest(); - } catch (JsonProcessingException e) { - throw new CborSerializationException(e); - } - } - public UnmaskedPredicateReference getReference(TokenType tokenType) { return UnmaskedPredicateReference.create( tokenType, diff --git a/src/main/java/org/unicitylabs/sdk/token/NameTagTokenState.java b/src/main/java/org/unicitylabs/sdk/token/NameTagTokenState.java deleted file mode 100644 index 03bfe4e..0000000 --- a/src/main/java/org/unicitylabs/sdk/token/NameTagTokenState.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.unicitylabs.sdk.token; - -import org.unicitylabs.sdk.address.Address; -import org.unicitylabs.sdk.predicate.Predicate; -import java.nio.charset.StandardCharsets; - -public class NameTagTokenState extends TokenState { - private final Address address; - - public NameTagTokenState(Predicate unlockPredicate, Address address) { - super(unlockPredicate, address == null ? null : address.getAddress().getBytes(StandardCharsets.UTF_8)); - - this.address = address; - } - - public Address getAddress() { - return address; - } -} diff --git a/src/main/java/org/unicitylabs/sdk/transaction/NametagMintTransactionData.java b/src/main/java/org/unicitylabs/sdk/transaction/NametagMintTransactionData.java index 8985828..82bb2eb 100644 --- a/src/main/java/org/unicitylabs/sdk/transaction/NametagMintTransactionData.java +++ b/src/main/java/org/unicitylabs/sdk/transaction/NametagMintTransactionData.java @@ -14,8 +14,6 @@ public class NametagMintTransactionData extends public NametagMintTransactionData( String name, TokenType tokenType, - byte[] tokenData, - TokenCoinData coinData, Address recipient, byte[] salt, Address targetAddress @@ -23,15 +21,11 @@ public NametagMintTransactionData( super( TokenId.fromNameTag(name), tokenType, - tokenData, - coinData, + targetAddress.getAddress().getBytes(StandardCharsets.UTF_8), + null, recipient, salt, - targetAddress == null - ? null - : new DataHasher(HashAlgorithm.SHA256) - .update(targetAddress.getAddress().getBytes(StandardCharsets.UTF_8)) - .digest(), + null, null ); } diff --git a/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java b/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java index cb87a1a..149ac29 100644 --- a/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java +++ b/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java @@ -4,18 +4,16 @@ import java.nio.charset.StandardCharsets; import java.util.List; - import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.unicitylabs.sdk.StateTransitionClient; -import org.unicitylabs.sdk.address.Address; import org.unicitylabs.sdk.address.ProxyAddress; import org.unicitylabs.sdk.api.SubmitCommitmentResponse; import org.unicitylabs.sdk.api.SubmitCommitmentStatus; -import org.unicitylabs.sdk.hash.DataHasher; import org.unicitylabs.sdk.hash.HashAlgorithm; import org.unicitylabs.sdk.predicate.MaskedPredicate; -import org.unicitylabs.sdk.predicate.Predicate; +import org.unicitylabs.sdk.predicate.UnmaskedPredicate; +import org.unicitylabs.sdk.predicate.UnmaskedPredicateReference; import org.unicitylabs.sdk.serializer.UnicityObjectMapper; import org.unicitylabs.sdk.signing.SigningService; import org.unicitylabs.sdk.token.Token; @@ -30,18 +28,20 @@ import org.unicitylabs.sdk.utils.TokenUtils; /** - * Alice has a nametag and acts as an escrow for the swap - * Bob transfers token to Alice - * Carol transfers token to Alice + * Alice has a nametag and acts as an escrow for the swap Bob transfers token to Alice Carol + * transfers token to Alice *

- * Alice transfers Bob's token to Carol - * Alice transfers Carol's token to Bob + * Alice transfers Bob's token to Carol Alice transfers Carol's token to Bob *

* Everyone's happy :) */ public abstract class BaseEscrowSwapTest { protected StateTransitionClient client; + private final TokenType tokenType = new TokenType(HexConverter.decode( + "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509")); + + private final byte[] ALICE_SECRET = "ALICE_SECRET".getBytes(StandardCharsets.UTF_8); private final byte[] BOB_SECRET = "BOB_SECRET".getBytes(StandardCharsets.UTF_8); private final byte[] CAROL_SECRET = "CAROL_SECRET".getBytes(StandardCharsets.UTF_8); @@ -50,16 +50,21 @@ public abstract class BaseEscrowSwapTest { private final String BOB_NAMETAG = String.format("BOB_%s", System.currentTimeMillis()); private final String CAROL_NAMETAG = String.format("CAROL_%s", System.currentTimeMillis()); - private String[] transferToken(Token token, byte[] secret, String nametag) throws Exception { + private String[] transferToken(Token token, SigningService signingService, String nametag) throws Exception { TransferCommitment commitment = TransferCommitment.create( token, ProxyAddress.create(nametag), randomBytes(32), null, null, - SigningService.createFromSecret(secret, token.getState().getUnlockPredicate().getNonce()) + signingService ); + System.out.println("TRANSFER"); + System.out.println(commitment.getTransactionData().getSourceState().getUnlockPredicate()); + System.out.println(commitment.getTransactionData().getSourceState().getUnlockPredicate().calculateHash(token.getId(), token.getType())); + System.out.println(commitment.getTransactionData().getSourceState().calculateHash(token.getId(), token.getType())); + SubmitCommitmentResponse response = this.client.submitCommitment(token, commitment).get(); if (response.getStatus() != SubmitCommitmentStatus.SUCCESS) { throw new RuntimeException("Failed to submit transfer commitment: " + response); @@ -77,8 +82,7 @@ private Token mintToken(byte[] secret) throws Exception { this.client, secret, new TokenId(randomBytes(32)), - new TokenType(HexConverter.decode( - "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509")), + this.tokenType, randomBytes(32), null, randomBytes(32), @@ -87,157 +91,119 @@ private Token mintToken(byte[] secret) throws Exception { ); } - private Token receiveToken(String[] tokenInfo, byte[] secret, - NametagWrapper nametagToken) throws Exception { + private Token receiveToken(String[] tokenInfo, SigningService signingService, + Token nametagToken) throws Exception { Token token = UnicityObjectMapper.JSON.readValue(tokenInfo[0], Token.class); Transaction transaction = UnicityObjectMapper.JSON.readValue( tokenInfo[1], UnicityObjectMapper.JSON.getTypeFactory() .constructParametricType(Transaction.class, TransferTransactionData.class)); - byte[] nonce = randomBytes(32); TokenState state = new TokenState( - MaskedPredicate.create( - SigningService.createFromSecret(secret, nonce), + UnmaskedPredicate.create( + signingService, HashAlgorithm.SHA256, - nonce + transaction.getData().getSalt() ), null ); - nametagToken.updateNameTag(this.client, secret, - state.getUnlockPredicate().getReference(token.getType()).toAddress()); - return this.client.finalizeTransaction( token, state, transaction, - List.of(nametagToken.getNametagToken()) + List.of(nametagToken) ); } @Test void testEscrow() throws Exception { // Make nametags unique for each test run + Token bobToken = mintToken(BOB_SECRET); String[] bobSerializedData = transferToken( - mintToken(BOB_SECRET), - BOB_SECRET, + bobToken, + SigningService.createFromSecret(BOB_SECRET, bobToken.getState().getUnlockPredicate().getNonce()), ALICE_NAMETAG ); + + Token carolToken = mintToken(CAROL_SECRET); String[] carolSerializedData = transferToken( - mintToken(CAROL_SECRET), - CAROL_SECRET, + carolToken, + SigningService.createFromSecret(CAROL_SECRET, carolToken.getState().getUnlockPredicate().getNonce()), ALICE_NAMETAG ); - NametagWrapper aliceNametagToken = new NametagWrapper( - TokenUtils.mintNametagToken( - this.client, - ALICE_SECRET, - new TokenType(HexConverter.decode( - "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509")), - randomBytes(32), - null, - ALICE_NAMETAG, - null, - randomBytes(32), - randomBytes(32) - ) + Token aliceNametagToken = TokenUtils.mintNametagToken( + this.client, + ALICE_SECRET, + this.tokenType, + ALICE_NAMETAG, + UnmaskedPredicateReference.create( + this.tokenType, + SigningService.createFromSecret(ALICE_SECRET, null), + HashAlgorithm.SHA256 + ).toAddress(), + randomBytes(32), + randomBytes(32) ); - Token aliceBobToken = receiveToken(bobSerializedData, ALICE_SECRET, aliceNametagToken); + Token aliceBobToken = receiveToken( + bobSerializedData, + SigningService.createFromSecret(ALICE_SECRET, null), + aliceNametagToken + ); Assertions.assertTrue(aliceBobToken.verify().isSuccessful()); - Token aliceCarolToken = receiveToken(carolSerializedData, ALICE_SECRET, aliceNametagToken); + Token aliceCarolToken = receiveToken( + carolSerializedData, + SigningService.createFromSecret(ALICE_SECRET, null), + aliceNametagToken + ); Assertions.assertTrue(aliceCarolToken.verify().isSuccessful()); Token aliceToCarolToken = receiveToken( - transferToken(aliceBobToken, ALICE_SECRET, CAROL_NAMETAG), - CAROL_SECRET, - new NametagWrapper( - TokenUtils.mintNametagToken( - this.client, - CAROL_SECRET, - new TokenType(HexConverter.decode( - "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509")), - randomBytes(32), - null, - CAROL_NAMETAG, - null, - randomBytes(32), - randomBytes(32) - ) - )); + transferToken( + aliceBobToken, + SigningService.createFromSecret(ALICE_SECRET, null), + CAROL_NAMETAG + ), + SigningService.createFromSecret(CAROL_SECRET, null), + TokenUtils.mintNametagToken( + this.client, + CAROL_SECRET, + this.tokenType, + CAROL_NAMETAG, + UnmaskedPredicateReference.create( + this.tokenType, + SigningService.createFromSecret(CAROL_SECRET, null), + HashAlgorithm.SHA256 + ).toAddress(), + randomBytes(32), + randomBytes(32) + ) + ); Assertions.assertTrue(aliceToCarolToken.verify().isSuccessful()); Token aliceToBobToken = receiveToken( - transferToken(aliceCarolToken, ALICE_SECRET, BOB_NAMETAG), - BOB_SECRET, - new NametagWrapper( - TokenUtils.mintNametagToken( - this.client, - BOB_SECRET, - new TokenType(HexConverter.decode( - "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509")), - randomBytes(32), - null, - BOB_NAMETAG, - null, - randomBytes(32), - randomBytes(32) - ) - )); + transferToken( + aliceCarolToken, + SigningService.createFromSecret(ALICE_SECRET, null), + BOB_NAMETAG + ), + SigningService.createFromSecret(BOB_SECRET, null), + TokenUtils.mintNametagToken( + this.client, + BOB_SECRET, + this.tokenType, + BOB_NAMETAG, + UnmaskedPredicateReference.create( + this.tokenType, + SigningService.createFromSecret(BOB_SECRET, null), + HashAlgorithm.SHA256 + ).toAddress(), + randomBytes(32), + randomBytes(32) + ) + ); Assertions.assertTrue(aliceToBobToken.verify().isSuccessful()); } - - static class NametagWrapper { - - private Token nametagToken; - - public NametagWrapper(Token nametagToken) { - this.nametagToken = nametagToken; - } - - public Token getNametagToken() { - return this.nametagToken; - } - - public void updateNameTag(StateTransitionClient client, byte[] secret, Address address) - throws Exception { - byte[] nonce = randomBytes(32); - Predicate predicate = MaskedPredicate.create( - SigningService.createFromSecret(secret, nonce), - HashAlgorithm.SHA256, - nonce - ); - - TransferCommitment commitment = TransferCommitment.create( - this.nametagToken, - predicate.getReference(this.nametagToken.getType()).toAddress(), - randomBytes(32), - new DataHasher(HashAlgorithm.SHA256) - .update(address.getAddress().getBytes(StandardCharsets.UTF_8)) - .digest(), - null, - SigningService.createFromSecret( - secret, - this.nametagToken.getState().getUnlockPredicate().getNonce() - ) - ); - - SubmitCommitmentResponse response = client.submitCommitment(this.nametagToken, commitment) - .get(); - if (response.getStatus() != SubmitCommitmentStatus.SUCCESS) { - throw new RuntimeException("Failed to submit transfer commitment: " + response); - } - - this.nametagToken = client.finalizeTransaction( - this.nametagToken, - new TokenState(predicate, address.getAddress().getBytes(StandardCharsets.UTF_8)), - commitment.toTransaction( - this.nametagToken, - InclusionProofUtils.waitInclusionProof(client, commitment).get() - ) - ); - } - } } diff --git a/src/test/java/org/unicitylabs/sdk/common/split/BaseTokenSplitTest.java b/src/test/java/org/unicitylabs/sdk/common/split/BaseTokenSplitTest.java index b0c5101..f591cda 100644 --- a/src/test/java/org/unicitylabs/sdk/common/split/BaseTokenSplitTest.java +++ b/src/test/java/org/unicitylabs/sdk/common/split/BaseTokenSplitTest.java @@ -10,13 +10,12 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.unicitylabs.sdk.StateTransitionClient; -import org.unicitylabs.sdk.address.Address; import org.unicitylabs.sdk.address.ProxyAddress; import org.unicitylabs.sdk.api.SubmitCommitmentResponse; import org.unicitylabs.sdk.api.SubmitCommitmentStatus; -import org.unicitylabs.sdk.hash.DataHasher; import org.unicitylabs.sdk.hash.HashAlgorithm; -import org.unicitylabs.sdk.predicate.MaskedPredicate; +import org.unicitylabs.sdk.predicate.UnmaskedPredicate; +import org.unicitylabs.sdk.predicate.UnmaskedPredicateReference; import org.unicitylabs.sdk.signing.SigningService; import org.unicitylabs.sdk.token.Token; import org.unicitylabs.sdk.token.TokenId; @@ -30,6 +29,7 @@ import org.unicitylabs.sdk.transaction.split.SplitMintReason; import org.unicitylabs.sdk.transaction.split.TokenSplitBuilder; import org.unicitylabs.sdk.transaction.split.TokenSplitBuilder.TokenSplit; +import org.unicitylabs.sdk.util.HexConverter; import org.unicitylabs.sdk.util.InclusionProofUtils; import org.unicitylabs.sdk.utils.TokenUtils; @@ -39,13 +39,15 @@ public abstract class BaseTokenSplitTest { @Test void testTokenSplitFullAmounts() throws Exception { + TokenType tokenType = new TokenType(HexConverter.decode( + "f8aa13834268d29355ff12183066f0cb902003629bbc5eb9ef0efbe397867509")); byte[] secret = "SECRET".getBytes(StandardCharsets.UTF_8); Token token = TokenUtils.mintToken( this.client, secret, new TokenId(randomBytes(32)), - new TokenType(randomBytes(32)), + tokenType, randomBytes(32), new TokenCoinData(Map.of( new CoinId("test_eur".getBytes(StandardCharsets.UTF_8)), @@ -64,14 +66,18 @@ void testTokenSplitFullAmounts() throws Exception { this.client, secret, nametag, - null + UnmaskedPredicateReference.create( + tokenType, + SigningService.createFromSecret(secret, null), + HashAlgorithm.SHA256 + ).toAddress() ); TokenSplitBuilder builder = new TokenSplitBuilder(); TokenSplit split = builder .createToken( new TokenId(randomBytes(32)), - new TokenType(randomBytes(32)), + tokenType, null, new TokenCoinData(Map.of( new CoinId("test_eur".getBytes(StandardCharsets.UTF_8)), @@ -83,7 +89,7 @@ void testTokenSplitFullAmounts() throws Exception { ) .createToken( new TokenId(randomBytes(32)), - new TokenType(randomBytes(32)), + tokenType, null, new TokenCoinData(Map.of( new CoinId("test_usd".getBytes(StandardCharsets.UTF_8)), @@ -126,61 +132,14 @@ void testTokenSplitFullAmounts() throws Exception { response.getStatus())); } - byte[] nonce = randomBytes(32); TokenState state = new TokenState( - MaskedPredicate.create( - SigningService.createFromSecret(secret, nonce), + UnmaskedPredicate.create( + SigningService.createFromSecret(secret, null), HashAlgorithm.SHA256, - nonce + commitment.getTransactionData().getSalt() ), null ); - Address address = state.getUnlockPredicate() - .getReference( - commitment.getTransactionData().getTokenType() - ) - .toAddress(); - - byte[] nametagNonce = randomBytes(32); - TokenState nametagTokenState = new TokenState( - MaskedPredicate.create( - SigningService.createFromSecret(secret, nametagNonce), - HashAlgorithm.SHA256, - nametagNonce - ), - address.getAddress().getBytes(StandardCharsets.UTF_8) - ); - - TransferCommitment nametagCommitment = TransferCommitment.create( - nametagToken, - nametagTokenState.getUnlockPredicate().getReference(nametagToken.getType()).toAddress(), - randomBytes(32), - new DataHasher(HashAlgorithm.SHA256) - .update(address.getAddress().getBytes(StandardCharsets.UTF_8)) - .digest(), - null, - SigningService.createFromSecret( - secret, - nametagToken.getState().getUnlockPredicate().getNonce() - ) - ); - - SubmitCommitmentResponse nametagTransferResponse = this.client - .submitCommitment(nametagToken, nametagCommitment) - .get(); - if (nametagTransferResponse.getStatus() != SubmitCommitmentStatus.SUCCESS) { - throw new Exception(String.format("Failed to submit nametag transfer commitment: %s", - response.getStatus())); - } - - nametagToken = this.client.finalizeTransaction( - nametagToken, - nametagTokenState, - nametagCommitment.toTransaction( - nametagToken, - InclusionProofUtils.waitInclusionProof(this.client, nametagCommitment).get() - ) - ); Token> splitToken = new Token<>( state, diff --git a/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java b/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java index 655ae6e..c93bee6 100644 --- a/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java +++ b/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java @@ -26,7 +26,6 @@ import org.unicitylabs.sdk.predicate.UnmaskedPredicate; import org.unicitylabs.sdk.predicate.UnmaskedPredicateReference; import org.unicitylabs.sdk.signing.SigningService; -import org.unicitylabs.sdk.token.NameTagTokenState; import org.unicitylabs.sdk.token.Token; import org.unicitylabs.sdk.token.TokenId; import org.unicitylabs.sdk.token.TokenState; @@ -149,11 +148,11 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti ); // Bob prepares to receive the token - byte[] bobNonce = randomBytes(32); - SigningService bobSigningService = SigningService.createFromSecret(BOB_SECRET, bobNonce); - MaskedPredicate bobPredicate = MaskedPredicate.create(bobSigningService, HashAlgorithm.SHA256, - bobNonce); - DirectAddress bobAddress = bobPredicate.getReference(tokenType).toAddress(); + DirectAddress bobAddress = UnmaskedPredicateReference.create( + tokenType, + SigningService.createFromSecret(BOB_SECRET, null), + HashAlgorithm.SHA256 + ).toAddress(); // Bob mints a name tag tokens @@ -170,8 +169,6 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti new NametagMintTransactionData<>( bobNameTag, bobNametagTokenType, - new byte[10], - null, bobNametagAddress, randomBytes(32), bobAddress @@ -191,21 +188,30 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti ).get() ); Token bobNametagToken = new Token<>( - new NameTagTokenState(bobNametagPredicate, bobAddress), + new TokenState(bobNametagPredicate, null), bobNametagGenesis ); // Bob finalizes the token Token bobToken = client.finalizeTransaction( aliceToken, - new TokenState(bobPredicate, bobStateData), + new TokenState( + UnmaskedPredicate.create( + SigningService.createFromSecret(BOB_SECRET, null), + HashAlgorithm.SHA256, + aliceToBobTransferTransaction.getData().getSalt() + ), + bobStateData + ), aliceToBobTransferTransaction, List.of(bobNametagToken) ); // Verify Bob is now the owner assertTrue(bobToken.verify().isSuccessful()); - assertTrue(bobToken.getState().getUnlockPredicate().isOwner(bobSigningService.getPublicKey())); + assertTrue(bobToken.getState().getUnlockPredicate() + .isOwner(SigningService.createFromSecret(BOB_SECRET, null).getPublicKey()) + ); assertEquals(aliceToken.getId(), bobToken.getId()); assertEquals(aliceToken.getType(), bobToken.getType()); @@ -223,7 +229,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti randomBytes(32), null, null, - bobSigningService + SigningService.createFromSecret(BOB_SECRET, null) ); SubmitCommitmentResponse bobToCarolTransferSubmitResponse = client.submitCommitment( bobToken, @@ -289,58 +295,6 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti carolToBobInclusionProof ); - byte[] bobNametagSecondUseNonce = randomBytes(32); - NameTagTokenState nametagSecondUseTokenState = new NameTagTokenState( - MaskedPredicate.create( - SigningService.createFromSecret(BOB_SECRET, bobNametagSecondUseNonce), - HashAlgorithm.SHA256, - bobNametagSecondUseNonce - ), - UnmaskedPredicateReference.create( - carolToken.getType(), - SigningService.createFromSecret(BOB_SECRET, null), - HashAlgorithm.SHA256 - ).toAddress() - ); - - TransferCommitment nametagSecondUseCommitment = TransferCommitment.create( - bobNametagToken, - nametagSecondUseTokenState.getUnlockPredicate().getReference(bobNametagToken.getType()) - .toAddress(), - randomBytes(32), - new DataHasher(HashAlgorithm.SHA256) - .update( - nametagSecondUseTokenState.getAddress() - .getAddress().getBytes(StandardCharsets.UTF_8) - ) - .digest(), - null, - SigningService.createFromSecret( - BOB_SECRET, - bobNametagToken.getState().getUnlockPredicate().getNonce() - ) - ); - SubmitCommitmentResponse nametagSecondUseResponse = client.submitCommitment( - bobNametagToken, - nametagSecondUseCommitment - ).get(); - - if (nametagSecondUseResponse.getStatus() != SubmitCommitmentStatus.SUCCESS) { - throw new Exception(String.format("Failed to submit nametag transfer commitment: %s", - nametagMintResponse.getStatus())); - } - - Token bobSecondUseNametag = client.finalizeTransaction( - bobNametagToken, - nametagSecondUseTokenState, - nametagSecondUseCommitment.toTransaction( - bobNametagToken, - InclusionProofUtils.waitInclusionProof(client, nametagSecondUseCommitment).get() - ) - ); - - Assertions.assertTrue(bobSecondUseNametag.verify().isSuccessful()); - Token carolToBobToken = client.finalizeTransaction( carolToken, new TokenState( @@ -352,7 +306,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti null ), carolToBobTransaction, - List.of(bobSecondUseNametag) + List.of(bobNametagToken) ); assertTrue(carolToBobToken.verify().isSuccessful()); diff --git a/src/test/java/org/unicitylabs/sdk/token/TokenTest.java b/src/test/java/org/unicitylabs/sdk/token/TokenTest.java index 84d7c29..419d7b5 100644 --- a/src/test/java/org/unicitylabs/sdk/token/TokenTest.java +++ b/src/test/java/org/unicitylabs/sdk/token/TokenTest.java @@ -41,25 +41,21 @@ public void testJsonSerialization() throws IOException { ); byte[] nametagNonce = TestUtils.randomBytes(32); - NameTagTokenState nametagTokenState = new NameTagTokenState( - MaskedPredicate.create( - SigningService.createFromSecret(TestUtils.randomBytes(32), nametagNonce), - HashAlgorithm.SHA256, - nametagNonce), - DirectAddress.create(new DataHash(HashAlgorithm.SHA256, TestUtils.randomBytes(32))) - ); MintTransactionData nametagGenesisData = new NametagMintTransactionData<>( UUID.randomUUID().toString(), new TokenType(TestUtils.randomBytes(32)), - TestUtils.randomBytes(5), - null, DirectAddress.create(new DataHash(HashAlgorithm.SHA256, TestUtils.randomBytes(32))), TestUtils.randomBytes(32), - nametagTokenState.getAddress() + DirectAddress.create(new DataHash(HashAlgorithm.SHA256, TestUtils.randomBytes(32))) ); Token nametagToken = new Token<>( - nametagTokenState, + new TokenState( + MaskedPredicate.create( + SigningService.createFromSecret(TestUtils.randomBytes(32), nametagNonce), + HashAlgorithm.SHA256, + nametagNonce), + null), new Transaction<>( nametagGenesisData, new InclusionProof( diff --git a/src/test/java/org/unicitylabs/sdk/utils/TokenUtils.java b/src/test/java/org/unicitylabs/sdk/utils/TokenUtils.java index 4f68142..46b07d7 100644 --- a/src/test/java/org/unicitylabs/sdk/utils/TokenUtils.java +++ b/src/test/java/org/unicitylabs/sdk/utils/TokenUtils.java @@ -11,7 +11,6 @@ import org.unicitylabs.sdk.hash.HashAlgorithm; import org.unicitylabs.sdk.predicate.MaskedPredicate; import org.unicitylabs.sdk.signing.SigningService; -import org.unicitylabs.sdk.token.NameTagTokenState; import org.unicitylabs.sdk.token.Token; import org.unicitylabs.sdk.token.TokenId; import org.unicitylabs.sdk.token.TokenState; @@ -106,8 +105,6 @@ public static Token mintNametagToken( client, secret, new TokenType(randomBytes(32)), - randomBytes(32), - randomCoinData(2), nametag, targetAddress, randomBytes(32), @@ -119,8 +116,6 @@ public static Token mintNametagToken( StateTransitionClient client, byte[] secret, TokenType tokenType, - byte[] tokenData, - TokenCoinData coinData, String nametag, Address targetAddress, byte[] nonce, @@ -135,14 +130,11 @@ public static Token mintNametagToken( ); Address address = predicate.getReference(tokenType).toAddress(); - TokenState tokenState = new NameTagTokenState(predicate, targetAddress); MintCommitment> commitment = MintCommitment.create( new NametagMintTransactionData<>( nametag, tokenType, - tokenData, - coinData, address, salt, targetAddress @@ -166,7 +158,7 @@ public static Token mintNametagToken( // Create mint transaction return new Token<>( - tokenState, + new TokenState(predicate, null), commitment.toTransaction(inclusionProof) ); } From 2c71fc7a86b3e6a8b84c5ba306cf3c7dab5efd00 Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Wed, 10 Sep 2025 17:07:26 +0400 Subject: [PATCH 6/8] Fix code style --- .../json/predicate/MaskedPredicateJson.java | 2 +- .../json/predicate/UnmaskedPredicateJson.java | 2 +- .../NametagMintTransactionData.java | 5 +---- .../sdk/common/BaseEscrowSwapTest.java | 1 - ...ionalUnsignedPredicateDoubleSpendTest.java | 14 ++++++++---- .../unicitylabs/sdk/hash/DataHashTest.java | 4 ++-- .../sdk/mtree/MerkleTreePathStepTest.java | 5 ++--- .../sdk/mtree/MerkleTreePathTest.java | 12 +++++----- .../split/TokenSplitBuilderTest.java | 22 +++++++++---------- 9 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/main/java/org/unicitylabs/sdk/serializer/json/predicate/MaskedPredicateJson.java b/src/main/java/org/unicitylabs/sdk/serializer/json/predicate/MaskedPredicateJson.java index dc40041..7779edd 100644 --- a/src/main/java/org/unicitylabs/sdk/serializer/json/predicate/MaskedPredicateJson.java +++ b/src/main/java/org/unicitylabs/sdk/serializer/json/predicate/MaskedPredicateJson.java @@ -52,7 +52,7 @@ public static class Deserializer extends @Override public MaskedPredicate deserialize(JsonParser p, DeserializationContext ctx) throws IOException { - PredicateType type = null; + PredicateType type; byte[] publicKey = null; String algorithm = null; HashAlgorithm hashAlgorithm = null; diff --git a/src/main/java/org/unicitylabs/sdk/serializer/json/predicate/UnmaskedPredicateJson.java b/src/main/java/org/unicitylabs/sdk/serializer/json/predicate/UnmaskedPredicateJson.java index 441075f..9d04710 100644 --- a/src/main/java/org/unicitylabs/sdk/serializer/json/predicate/UnmaskedPredicateJson.java +++ b/src/main/java/org/unicitylabs/sdk/serializer/json/predicate/UnmaskedPredicateJson.java @@ -53,7 +53,7 @@ public static class Deserializer extends @Override public UnmaskedPredicate deserialize(JsonParser p, DeserializationContext ctx) throws IOException { - PredicateType type = null; + PredicateType type; byte[] publicKey = null; String algorithm = null; HashAlgorithm hashAlgorithm = null; diff --git a/src/main/java/org/unicitylabs/sdk/transaction/NametagMintTransactionData.java b/src/main/java/org/unicitylabs/sdk/transaction/NametagMintTransactionData.java index 82bb2eb..6c42436 100644 --- a/src/main/java/org/unicitylabs/sdk/transaction/NametagMintTransactionData.java +++ b/src/main/java/org/unicitylabs/sdk/transaction/NametagMintTransactionData.java @@ -1,12 +1,9 @@ package org.unicitylabs.sdk.transaction; +import java.nio.charset.StandardCharsets; import org.unicitylabs.sdk.address.Address; -import org.unicitylabs.sdk.hash.DataHasher; -import org.unicitylabs.sdk.hash.HashAlgorithm; import org.unicitylabs.sdk.token.TokenId; import org.unicitylabs.sdk.token.TokenType; -import org.unicitylabs.sdk.token.fungible.TokenCoinData; -import java.nio.charset.StandardCharsets; public class NametagMintTransactionData extends MintTransactionData { diff --git a/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java b/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java index 149ac29..e95c2a4 100644 --- a/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java +++ b/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java @@ -11,7 +11,6 @@ import org.unicitylabs.sdk.api.SubmitCommitmentResponse; import org.unicitylabs.sdk.api.SubmitCommitmentStatus; import org.unicitylabs.sdk.hash.HashAlgorithm; -import org.unicitylabs.sdk.predicate.MaskedPredicate; import org.unicitylabs.sdk.predicate.UnmaskedPredicate; import org.unicitylabs.sdk.predicate.UnmaskedPredicateReference; import org.unicitylabs.sdk.serializer.UnicityObjectMapper; diff --git a/src/test/java/org/unicitylabs/sdk/functional/FunctionalUnsignedPredicateDoubleSpendTest.java b/src/test/java/org/unicitylabs/sdk/functional/FunctionalUnsignedPredicateDoubleSpendTest.java index 28f7aa8..997c8f6 100644 --- a/src/test/java/org/unicitylabs/sdk/functional/FunctionalUnsignedPredicateDoubleSpendTest.java +++ b/src/test/java/org/unicitylabs/sdk/functional/FunctionalUnsignedPredicateDoubleSpendTest.java @@ -29,7 +29,7 @@ import org.unicitylabs.sdk.utils.TokenUtils; public class FunctionalUnsignedPredicateDoubleSpendTest { - protected StateTransitionClient client = new StateTransitionClient(new TestAggregatorClient()); + protected final StateTransitionClient client = new StateTransitionClient(new TestAggregatorClient()); private final byte[] BOB_SECRET = "BOB_SECRET".getBytes(StandardCharsets.UTF_8); private String[] transferToken(Token token, byte[] secret, Address address) throws Exception { @@ -103,11 +103,17 @@ void testDoubleSpend() throws Exception { HashAlgorithm.SHA256 ); - Assertions.assertTrue(receiveToken(transferToken(token, BOB_SECRET, reference.toAddress()), BOB_SECRET).verify().isSuccessful()); + Assertions.assertTrue( + receiveToken( + transferToken(token, BOB_SECRET, reference.toAddress()), + BOB_SECRET + ).verify().isSuccessful()); RuntimeException ex = Assertions.assertThrows( RuntimeException.class, - () -> receiveToken(transferToken(token, BOB_SECRET, reference.toAddress()), - BOB_SECRET).verify().isSuccessful() + () -> receiveToken( + transferToken(token, BOB_SECRET, reference.toAddress()), + BOB_SECRET + ).verify() ); Assertions.assertInstanceOf(BranchExistsException.class, ex.getCause()); diff --git a/src/test/java/org/unicitylabs/sdk/hash/DataHashTest.java b/src/test/java/org/unicitylabs/sdk/hash/DataHashTest.java index 702551b..36947b0 100644 --- a/src/test/java/org/unicitylabs/sdk/hash/DataHashTest.java +++ b/src/test/java/org/unicitylabs/sdk/hash/DataHashTest.java @@ -33,9 +33,9 @@ public void testDataHashJsonSerialization() throws JsonProcessingException { objectMapper.readValue( "\"00000000000000000000000000000000000000000000000000000000000000000000\"", DataHash.class)); - JsonMappingException exception = Assertions.assertThrows(JsonMappingException.class, + Assertions.assertThrows(JsonMappingException.class, () -> objectMapper.readValue("[]", DataHash.class)); - exception = Assertions.assertThrows(JsonMappingException.class, + Assertions.assertThrows(JsonMappingException.class, () -> objectMapper.readValue("\"AABBGG\"", DataHash.class)); } } diff --git a/src/test/java/org/unicitylabs/sdk/mtree/MerkleTreePathStepTest.java b/src/test/java/org/unicitylabs/sdk/mtree/MerkleTreePathStepTest.java index e7eaad2..b1f0486 100644 --- a/src/test/java/org/unicitylabs/sdk/mtree/MerkleTreePathStepTest.java +++ b/src/test/java/org/unicitylabs/sdk/mtree/MerkleTreePathStepTest.java @@ -18,9 +18,8 @@ public class MerkleTreePathStepTest { @Test public void testConstructorThrowsOnNullArguments() { - Exception exception = assertThrows(NullPointerException.class, () -> { - new SparseMerkleTreePathStep(null, null, null); - }); + Exception exception = assertThrows(NullPointerException.class, + () -> new SparseMerkleTreePathStep(null, null, null)); assertEquals("path cannot be null", exception.getMessage()); } diff --git a/src/test/java/org/unicitylabs/sdk/mtree/MerkleTreePathTest.java b/src/test/java/org/unicitylabs/sdk/mtree/MerkleTreePathTest.java index 0c5e21c..85a5e40 100644 --- a/src/test/java/org/unicitylabs/sdk/mtree/MerkleTreePathTest.java +++ b/src/test/java/org/unicitylabs/sdk/mtree/MerkleTreePathTest.java @@ -21,13 +21,13 @@ public class MerkleTreePathTest { @Test public void testConstructorThrowsOnNullArguments() { - Exception exception = assertThrows(NullPointerException.class, () -> { - new SparseMerkleTreePath(null, null); - }); + Exception exception = assertThrows(NullPointerException.class, + () -> new SparseMerkleTreePath(null, null) + ); assertEquals("rootHash cannot be null", exception.getMessage()); - exception = assertThrows(NullPointerException.class, () -> { - new SparseMerkleTreePath(new DataHash(HashAlgorithm.SHA256, new byte[32]), null); - }); + exception = assertThrows(NullPointerException.class, + () -> new SparseMerkleTreePath(new DataHash(HashAlgorithm.SHA256, new byte[32]), null) + ); assertEquals("steps cannot be null", exception.getMessage()); } diff --git a/src/test/java/org/unicitylabs/sdk/transaction/split/TokenSplitBuilderTest.java b/src/test/java/org/unicitylabs/sdk/transaction/split/TokenSplitBuilderTest.java index 5459d71..cd6818e 100644 --- a/src/test/java/org/unicitylabs/sdk/transaction/split/TokenSplitBuilderTest.java +++ b/src/test/java/org/unicitylabs/sdk/transaction/split/TokenSplitBuilderTest.java @@ -82,17 +82,17 @@ public void testTokenSplitIntoMultipleTokens() TokenSplitBuilder builder = new TokenSplitBuilder(); - Assertions.assertThrows(IllegalArgumentException.class, () -> { - builder.createToken( - new TokenId(UUID.randomUUID().toString().getBytes()), - token.getType(), - null, - new TokenCoinData(Map.of()), - predicate.getReference(token.getType()).toAddress(), - new byte[20], - null - ); - }); + Assertions.assertThrows(IllegalArgumentException.class, + () -> builder.createToken( + new TokenId(UUID.randomUUID().toString().getBytes()), + token.getType(), + null, + new TokenCoinData(Map.of()), + predicate.getReference(token.getType()).toAddress(), + new byte[20], + null + ) + ); builder.createToken( new TokenId(UUID.randomUUID().toString().getBytes()), From 92a3bf82eeca30878d34d67a51a7ecdc49c10d72 Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Wed, 10 Sep 2025 23:19:17 +0400 Subject: [PATCH 7/8] Remove debug System.out.println from tests --- .../java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java b/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java index e95c2a4..86d9b7a 100644 --- a/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java +++ b/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java @@ -59,11 +59,6 @@ private String[] transferToken(Token token, SigningService signingService, St signingService ); - System.out.println("TRANSFER"); - System.out.println(commitment.getTransactionData().getSourceState().getUnlockPredicate()); - System.out.println(commitment.getTransactionData().getSourceState().getUnlockPredicate().calculateHash(token.getId(), token.getType())); - System.out.println(commitment.getTransactionData().getSourceState().calculateHash(token.getId(), token.getType())); - SubmitCommitmentResponse response = this.client.submitCommitment(token, commitment).get(); if (response.getStatus() != SubmitCommitmentStatus.SUCCESS) { throw new RuntimeException("Failed to submit transfer commitment: " + response); From 4ac55c28accef0fce0b69d5cac91be8447adb262 Mon Sep 17 00:00:00 2001 From: Martti Marran Date: Wed, 10 Sep 2025 23:52:27 +0400 Subject: [PATCH 8/8] Create SigningService method createFromMaskedSecret to improve usability --- .../sdk/signing/SigningService.java | 11 ++++++-- .../sdk/transaction/MintCommitment.java | 2 +- .../sdk/AndroidCompatibilityTest.java | 2 +- .../sdk/common/BaseEscrowSwapTest.java | 22 ++++++++-------- .../sdk/common/split/BaseTokenSplitTest.java | 6 ++--- .../org/unicitylabs/sdk/e2e/BasicE2ETest.java | 4 +-- .../unicitylabs/sdk/e2e/CommonTestFlow.java | 25 ++++++++++--------- ...edPredicateDoubleSpendPreventionTest.java} | 8 +++--- .../sdk/signing/SigningServiceTest.java | 2 +- .../org/unicitylabs/sdk/token/TokenTest.java | 8 +++--- .../org/unicitylabs/sdk/utils/TokenUtils.java | 4 +-- 11 files changed, 52 insertions(+), 42 deletions(-) rename src/test/java/org/unicitylabs/sdk/functional/{FunctionalUnsignedPredicateDoubleSpendTest.java => FunctionalUnsignedPredicateDoubleSpendPreventionTest.java} (93%) diff --git a/src/main/java/org/unicitylabs/sdk/signing/SigningService.java b/src/main/java/org/unicitylabs/sdk/signing/SigningService.java index e8c6471..1d4bc9c 100644 --- a/src/main/java/org/unicitylabs/sdk/signing/SigningService.java +++ b/src/main/java/org/unicitylabs/sdk/signing/SigningService.java @@ -79,9 +79,16 @@ public static byte[] generatePrivateKey() { } /** - * Create signing service from secret and optional nonce. + * Create signing service from secret. */ - public static SigningService createFromSecret(byte[] secret, byte[] nonce) { + public static SigningService createFromSecret(byte[] secret) { + return SigningService.createFromMaskedSecret(secret, null); + } + + /** + * Create signing service from secret and nonce. + */ + public static SigningService createFromMaskedSecret(byte[] secret, byte[] nonce) { DataHasher hasher = new DataHasher(HashAlgorithm.SHA256); hasher.update(secret); if (nonce != null) { diff --git a/src/main/java/org/unicitylabs/sdk/transaction/MintCommitment.java b/src/main/java/org/unicitylabs/sdk/transaction/MintCommitment.java index 374456d..76d6e52 100644 --- a/src/main/java/org/unicitylabs/sdk/transaction/MintCommitment.java +++ b/src/main/java/org/unicitylabs/sdk/transaction/MintCommitment.java @@ -40,7 +40,7 @@ public static > MintCommitment create( } public static SigningService createSigningService(MintTransactionData transactionData) { - return SigningService.createFromSecret(MINTER_SECRET, transactionData.getTokenId().getBytes()); + return SigningService.createFromMaskedSecret(MINTER_SECRET, transactionData.getTokenId().getBytes()); } public Transaction toTransaction(InclusionProof inclusionProof) { diff --git a/src/test/java/org/unicitylabs/sdk/AndroidCompatibilityTest.java b/src/test/java/org/unicitylabs/sdk/AndroidCompatibilityTest.java index a590b2c..9d00a69 100644 --- a/src/test/java/org/unicitylabs/sdk/AndroidCompatibilityTest.java +++ b/src/test/java/org/unicitylabs/sdk/AndroidCompatibilityTest.java @@ -27,7 +27,7 @@ void testCoreSDKFeaturesWorkOnAndroid() throws Exception { // Test 2: Signing Service (uses Bouncy Castle) byte[] secret = "test secret".getBytes(StandardCharsets.UTF_8); byte[] nonce = new byte[32]; - var signingService = SigningService.createFromSecret(secret, nonce); + var signingService = SigningService.createFromMaskedSecret(secret, nonce); assertNotNull(signingService.getPublicKey()); // Test 3: Token IDs and Types diff --git a/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java b/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java index 86d9b7a..f561448 100644 --- a/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java +++ b/src/test/java/org/unicitylabs/sdk/common/BaseEscrowSwapTest.java @@ -116,14 +116,14 @@ void testEscrow() throws Exception { Token bobToken = mintToken(BOB_SECRET); String[] bobSerializedData = transferToken( bobToken, - SigningService.createFromSecret(BOB_SECRET, bobToken.getState().getUnlockPredicate().getNonce()), + SigningService.createFromMaskedSecret(BOB_SECRET, bobToken.getState().getUnlockPredicate().getNonce()), ALICE_NAMETAG ); Token carolToken = mintToken(CAROL_SECRET); String[] carolSerializedData = transferToken( carolToken, - SigningService.createFromSecret(CAROL_SECRET, carolToken.getState().getUnlockPredicate().getNonce()), + SigningService.createFromMaskedSecret(CAROL_SECRET, carolToken.getState().getUnlockPredicate().getNonce()), ALICE_NAMETAG ); @@ -134,7 +134,7 @@ void testEscrow() throws Exception { ALICE_NAMETAG, UnmaskedPredicateReference.create( this.tokenType, - SigningService.createFromSecret(ALICE_SECRET, null), + SigningService.createFromSecret(ALICE_SECRET), HashAlgorithm.SHA256 ).toAddress(), randomBytes(32), @@ -143,13 +143,13 @@ void testEscrow() throws Exception { Token aliceBobToken = receiveToken( bobSerializedData, - SigningService.createFromSecret(ALICE_SECRET, null), + SigningService.createFromSecret(ALICE_SECRET), aliceNametagToken ); Assertions.assertTrue(aliceBobToken.verify().isSuccessful()); Token aliceCarolToken = receiveToken( carolSerializedData, - SigningService.createFromSecret(ALICE_SECRET, null), + SigningService.createFromSecret(ALICE_SECRET), aliceNametagToken ); Assertions.assertTrue(aliceCarolToken.verify().isSuccessful()); @@ -157,10 +157,10 @@ void testEscrow() throws Exception { Token aliceToCarolToken = receiveToken( transferToken( aliceBobToken, - SigningService.createFromSecret(ALICE_SECRET, null), + SigningService.createFromSecret(ALICE_SECRET), CAROL_NAMETAG ), - SigningService.createFromSecret(CAROL_SECRET, null), + SigningService.createFromSecret(CAROL_SECRET), TokenUtils.mintNametagToken( this.client, CAROL_SECRET, @@ -168,7 +168,7 @@ void testEscrow() throws Exception { CAROL_NAMETAG, UnmaskedPredicateReference.create( this.tokenType, - SigningService.createFromSecret(CAROL_SECRET, null), + SigningService.createFromSecret(CAROL_SECRET), HashAlgorithm.SHA256 ).toAddress(), randomBytes(32), @@ -180,10 +180,10 @@ void testEscrow() throws Exception { Token aliceToBobToken = receiveToken( transferToken( aliceCarolToken, - SigningService.createFromSecret(ALICE_SECRET, null), + SigningService.createFromSecret(ALICE_SECRET), BOB_NAMETAG ), - SigningService.createFromSecret(BOB_SECRET, null), + SigningService.createFromSecret(BOB_SECRET), TokenUtils.mintNametagToken( this.client, BOB_SECRET, @@ -191,7 +191,7 @@ void testEscrow() throws Exception { BOB_NAMETAG, UnmaskedPredicateReference.create( this.tokenType, - SigningService.createFromSecret(BOB_SECRET, null), + SigningService.createFromSecret(BOB_SECRET), HashAlgorithm.SHA256 ).toAddress(), randomBytes(32), diff --git a/src/test/java/org/unicitylabs/sdk/common/split/BaseTokenSplitTest.java b/src/test/java/org/unicitylabs/sdk/common/split/BaseTokenSplitTest.java index f591cda..5c1a221 100644 --- a/src/test/java/org/unicitylabs/sdk/common/split/BaseTokenSplitTest.java +++ b/src/test/java/org/unicitylabs/sdk/common/split/BaseTokenSplitTest.java @@ -68,7 +68,7 @@ void testTokenSplitFullAmounts() throws Exception { nametag, UnmaskedPredicateReference.create( tokenType, - SigningService.createFromSecret(secret, null), + SigningService.createFromSecret(secret), HashAlgorithm.SHA256 ).toAddress() ); @@ -103,7 +103,7 @@ void testTokenSplitFullAmounts() throws Exception { TransferCommitment burnCommitment = split.createBurnCommitment( randomBytes(32), - SigningService.createFromSecret(secret, token.getState().getUnlockPredicate().getNonce()) + SigningService.createFromMaskedSecret(secret, token.getState().getUnlockPredicate().getNonce()) ); SubmitCommitmentResponse burnCommitmentResponse = this.client @@ -134,7 +134,7 @@ void testTokenSplitFullAmounts() throws Exception { TokenState state = new TokenState( UnmaskedPredicate.create( - SigningService.createFromSecret(secret, null), + SigningService.createFromSecret(secret), HashAlgorithm.SHA256, commitment.getTransactionData().getSalt() ), diff --git a/src/test/java/org/unicitylabs/sdk/e2e/BasicE2ETest.java b/src/test/java/org/unicitylabs/sdk/e2e/BasicE2ETest.java index 7c38e92..475c21e 100644 --- a/src/test/java/org/unicitylabs/sdk/e2e/BasicE2ETest.java +++ b/src/test/java/org/unicitylabs/sdk/e2e/BasicE2ETest.java @@ -53,7 +53,7 @@ void testCommitmentPerformance() throws Exception { sr.nextBytes(stateBytes); DataHash stateHash = new DataHasher(HashAlgorithm.SHA256).update(stateBytes).digest(); DataHash txDataHash = new DataHasher(HashAlgorithm.SHA256).update("test commitment performance".getBytes()).digest(); - SigningService signingService = SigningService.createFromSecret(randomSecret, null); + SigningService signingService = SigningService.createFromSecret(randomSecret); RequestId requestId = RequestId.createFromImprint(signingService.getPublicKey(), stateHash.getImprint()); Authenticator auth = Authenticator.create(signingService, txDataHash, stateHash); SubmitCommitmentResponse response = aggregatorClient.submitCommitment(requestId, txDataHash, auth).get(); @@ -98,7 +98,7 @@ void testCommitmentPerformanceMultiThreaded() throws Exception { DataHash stateHash = new DataHasher(HashAlgorithm.SHA256).update(stateBytes).digest(); DataHash txDataHash = new DataHasher(HashAlgorithm.SHA256).update(txData).digest(); - SigningService signingService = SigningService.createFromSecret(randomSecret, null); + SigningService signingService = SigningService.createFromSecret(randomSecret); RequestId requestId = RequestId.createFromImprint(signingService.getPublicKey(), stateHash.getImprint()); Authenticator auth = Authenticator.create(signingService, txDataHash, stateHash); SubmitCommitmentResponse response = aggregatorClient.submitCommitment(requestId, txDataHash, auth).get(); diff --git a/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java b/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java index c93bee6..4572ed8 100644 --- a/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java +++ b/src/test/java/org/unicitylabs/sdk/e2e/CommonTestFlow.java @@ -65,7 +65,8 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti // Alice mints a token byte[] aliceNonce = randomBytes(32); - SigningService aliceSigningService = SigningService.createFromSecret(ALICE_SECRET, aliceNonce); + SigningService aliceSigningService = SigningService.createFromMaskedSecret(ALICE_SECRET, + aliceNonce); MaskedPredicate alicePredicate = MaskedPredicate.create( aliceSigningService, @@ -150,7 +151,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti // Bob prepares to receive the token DirectAddress bobAddress = UnmaskedPredicateReference.create( tokenType, - SigningService.createFromSecret(BOB_SECRET, null), + SigningService.createFromSecret(BOB_SECRET), HashAlgorithm.SHA256 ).toAddress(); @@ -158,7 +159,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti byte[] bobNametagNonce = randomBytes(32); MaskedPredicate bobNametagPredicate = MaskedPredicate.create( - SigningService.createFromSecret(BOB_SECRET, bobNametagNonce), + SigningService.createFromMaskedSecret(BOB_SECRET, bobNametagNonce), HashAlgorithm.SHA256, bobNametagNonce ); @@ -197,7 +198,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti aliceToken, new TokenState( UnmaskedPredicate.create( - SigningService.createFromSecret(BOB_SECRET, null), + SigningService.createFromSecret(BOB_SECRET), HashAlgorithm.SHA256, aliceToBobTransferTransaction.getData().getSalt() ), @@ -210,7 +211,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti // Verify Bob is now the owner assertTrue(bobToken.verify().isSuccessful()); assertTrue(bobToken.getState().getUnlockPredicate() - .isOwner(SigningService.createFromSecret(BOB_SECRET, null).getPublicKey()) + .isOwner(SigningService.createFromSecret(BOB_SECRET).getPublicKey()) ); assertEquals(aliceToken.getId(), bobToken.getId()); assertEquals(aliceToken.getType(), bobToken.getType()); @@ -218,7 +219,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti // Transfer to Carol with UnmaskedPredicate DirectAddress carolAddress = UnmaskedPredicateReference.create( tokenType, - SigningService.createFromSecret(CAROL_SECRET, null), + SigningService.createFromSecret(CAROL_SECRET), HashAlgorithm.SHA256).toAddress(); // Bob transfers to Carol (no custom data) @@ -229,7 +230,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti randomBytes(32), null, null, - SigningService.createFromSecret(BOB_SECRET, null) + SigningService.createFromSecret(BOB_SECRET) ); SubmitCommitmentResponse bobToCarolTransferSubmitResponse = client.submitCommitment( bobToken, @@ -252,7 +253,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti // Carol creates UnmaskedPredicate and finalizes UnmaskedPredicate carolPredicate = UnmaskedPredicate.create( - SigningService.createFromSecret(CAROL_SECRET, null), + SigningService.createFromSecret(CAROL_SECRET), HashAlgorithm.SHA256, bobToCarolTransaction.getData().getSalt() ); @@ -273,7 +274,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti randomBytes(32), null, null, - SigningService.createFromSecret(CAROL_SECRET, null) + SigningService.createFromSecret(CAROL_SECRET) ); SubmitCommitmentResponse carolToBobTransferSubmitResponse = client.submitCommitment( carolToken, @@ -299,7 +300,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti carolToken, new TokenState( UnmaskedPredicate.create( - SigningService.createFromSecret(BOB_SECRET, null), + SigningService.createFromSecret(BOB_SECRET), HashAlgorithm.SHA256, carolToBobTransaction.getData().getSalt() ), @@ -318,7 +319,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti TokenType splitTokenType = new TokenType(randomBytes(32)); byte[] splitTokenNonce = randomBytes(32); MaskedPredicate splitTokenPredicate = MaskedPredicate.create( - SigningService.createFromSecret(BOB_SECRET, splitTokenNonce), + SigningService.createFromMaskedSecret(BOB_SECRET, splitTokenNonce), HashAlgorithm.SHA256, splitTokenNonce ); @@ -346,7 +347,7 @@ public static void testTransferFlow(StateTransitionClient client) throws Excepti TransferCommitment burnCommitment = split.createBurnCommitment( randomBytes(32), - SigningService.createFromSecret(BOB_SECRET, null) + SigningService.createFromSecret(BOB_SECRET) ); if (client.submitCommitment(carolToBobToken, burnCommitment).get().getStatus() diff --git a/src/test/java/org/unicitylabs/sdk/functional/FunctionalUnsignedPredicateDoubleSpendTest.java b/src/test/java/org/unicitylabs/sdk/functional/FunctionalUnsignedPredicateDoubleSpendPreventionTest.java similarity index 93% rename from src/test/java/org/unicitylabs/sdk/functional/FunctionalUnsignedPredicateDoubleSpendTest.java rename to src/test/java/org/unicitylabs/sdk/functional/FunctionalUnsignedPredicateDoubleSpendPreventionTest.java index 997c8f6..4a2abf0 100644 --- a/src/test/java/org/unicitylabs/sdk/functional/FunctionalUnsignedPredicateDoubleSpendTest.java +++ b/src/test/java/org/unicitylabs/sdk/functional/FunctionalUnsignedPredicateDoubleSpendPreventionTest.java @@ -28,7 +28,7 @@ import org.unicitylabs.sdk.util.InclusionProofUtils; import org.unicitylabs.sdk.utils.TokenUtils; -public class FunctionalUnsignedPredicateDoubleSpendTest { +public class FunctionalUnsignedPredicateDoubleSpendPreventionTest { protected final StateTransitionClient client = new StateTransitionClient(new TestAggregatorClient()); private final byte[] BOB_SECRET = "BOB_SECRET".getBytes(StandardCharsets.UTF_8); @@ -39,7 +39,7 @@ private String[] transferToken(Token token, byte[] secret, Address address) t randomBytes(32), null, null, - SigningService.createFromSecret(secret, token.getState().getUnlockPredicate().getNonce()) + SigningService.createFromMaskedSecret(secret, token.getState().getUnlockPredicate().getNonce()) ); SubmitCommitmentResponse response = this.client.submitCommitment(token, commitment).get(); @@ -78,7 +78,7 @@ private Token receiveToken(String[] tokenInfo, byte[] secret) throws Exceptio TokenState state = new TokenState( UnmaskedPredicate.create( - SigningService.createFromSecret(secret, null), + SigningService.createFromSecret(secret), HashAlgorithm.SHA256, transaction.getData().getSalt() ), @@ -99,7 +99,7 @@ void testDoubleSpend() throws Exception { UnmaskedPredicateReference reference = UnmaskedPredicateReference.create( token.getType(), - SigningService.createFromSecret(BOB_SECRET, null), + SigningService.createFromSecret(BOB_SECRET), HashAlgorithm.SHA256 ); diff --git a/src/test/java/org/unicitylabs/sdk/signing/SigningServiceTest.java b/src/test/java/org/unicitylabs/sdk/signing/SigningServiceTest.java index b2e8397..a80136d 100644 --- a/src/test/java/org/unicitylabs/sdk/signing/SigningServiceTest.java +++ b/src/test/java/org/unicitylabs/sdk/signing/SigningServiceTest.java @@ -28,7 +28,7 @@ public void testCreateFromSecret() throws Exception { byte[] secret = "test secret".getBytes(StandardCharsets.UTF_8); byte[] nonce = "test nonce".getBytes(StandardCharsets.UTF_8); - SigningService signingService = SigningService.createFromSecret(secret, nonce); + SigningService signingService = SigningService.createFromMaskedSecret(secret, nonce); assertNotNull(signingService); assertNotNull(signingService.getPublicKey()); diff --git a/src/test/java/org/unicitylabs/sdk/token/TokenTest.java b/src/test/java/org/unicitylabs/sdk/token/TokenTest.java index 419d7b5..4b739b4 100644 --- a/src/test/java/org/unicitylabs/sdk/token/TokenTest.java +++ b/src/test/java/org/unicitylabs/sdk/token/TokenTest.java @@ -52,7 +52,7 @@ public void testJsonSerialization() throws IOException { Token nametagToken = new Token<>( new TokenState( MaskedPredicate.create( - SigningService.createFromSecret(TestUtils.randomBytes(32), nametagNonce), + SigningService.createFromMaskedSecret(TestUtils.randomBytes(32), nametagNonce), HashAlgorithm.SHA256, nametagNonce), null), @@ -72,8 +72,10 @@ public void testJsonSerialization() throws IOException { Token token = new Token<>( new TokenState( MaskedPredicate.create( - SigningService.createFromSecret(TestUtils.randomBytes(32), - genesisData.getTokenId().getBytes()), + SigningService.createFromMaskedSecret( + TestUtils.randomBytes(32), + genesisData.getTokenId().getBytes() + ), HashAlgorithm.SHA256, TestUtils.randomBytes(24)), null diff --git a/src/test/java/org/unicitylabs/sdk/utils/TokenUtils.java b/src/test/java/org/unicitylabs/sdk/utils/TokenUtils.java index 46b07d7..e9fcd50 100644 --- a/src/test/java/org/unicitylabs/sdk/utils/TokenUtils.java +++ b/src/test/java/org/unicitylabs/sdk/utils/TokenUtils.java @@ -49,7 +49,7 @@ public static Token mintToken( byte[] salt, DataHash dataHash ) throws Exception { - SigningService signingService = SigningService.createFromSecret(secret, nonce); + SigningService signingService = SigningService.createFromMaskedSecret(secret, nonce); MaskedPredicate predicate = MaskedPredicate.create( signingService, @@ -121,7 +121,7 @@ public static Token mintNametagToken( byte[] nonce, byte[] salt ) throws Exception { - SigningService signingService = SigningService.createFromSecret(secret, nonce); + SigningService signingService = SigningService.createFromMaskedSecret(secret, nonce); MaskedPredicate predicate = MaskedPredicate.create( signingService,