diff --git a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/AccountSet.java b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/AccountSet.java index b82f7b217..ace5b6994 100644 --- a/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/AccountSet.java +++ b/xrpl4j-core/src/main/java/org/xrpl/xrpl4j/model/transactions/AccountSet.java @@ -205,7 +205,11 @@ default void checkTickSize() { * */ enum AccountSetFlag { - + /** + * This flag will do nothing but exists to accurately deserialize AccountSet transactions whose {@code SetFlag} + * or {@code ClearFlag} fields are zero. + */ + NONE(0), /** * Require a destination tag to send transactions to this account. */ @@ -274,7 +278,7 @@ enum AccountSetFlag { */ DISALLOW_INCOMING_TRUSTLINE(15); - int value; + final int value; AccountSetFlag(int value) { this.value = value; diff --git a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/json/AccountSetJsonTests.java b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/json/AccountSetJsonTests.java index ce88119d4..25ce81b17 100644 --- a/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/json/AccountSetJsonTests.java +++ b/xrpl4j-core/src/test/java/org/xrpl/xrpl4j/model/transactions/json/AccountSetJsonTests.java @@ -153,4 +153,42 @@ public void testJsonWithEmptyFlags() throws JsonProcessingException, JSONExcepti assertCanSerializeAndDeserialize(accountSet, json); } + + @Test + void testJsonWithZeroClearFlagAndSetFlag() throws JSONException, JsonProcessingException { + AccountSet accountSet = AccountSet.builder() + .account(Address.of("rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn")) + .fee(XrpCurrencyAmount.ofDrops(12)) + .sequence(UnsignedInteger.valueOf(5)) + .domain("6578616D706C652E636F6D") + .setFlag(AccountSetFlag.NONE) + .messageKey("03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB") + .transferRate(UnsignedInteger.valueOf(1000000001)) + .tickSize(UnsignedInteger.valueOf(15)) + .clearFlag(AccountSetFlag.NONE) + .emailHash("f9879d71855b5ff21e4963273a886bfc") + .signingPublicKey( + PublicKey.fromBase16EncodedPublicKey("02356E89059A75438887F9FEE2056A2890DB82A68353BE9C0C0C8F89C0018B37FC") + ) + .mintAccount(Address.of("rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn")) + .build(); + + String json = "{\n" + + " \"TransactionType\":\"AccountSet\",\n" + + " \"Account\":\"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\",\n" + + " \"Fee\":\"12\",\n" + + " \"Sequence\":5,\n" + + " \"Domain\":\"6578616D706C652E636F6D\",\n" + + " \"SetFlag\":0,\n" + + " \"MessageKey\":\"03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB\",\n" + + " \"TransferRate\":1000000001,\n" + + " \"TickSize\":15,\n" + + " \"ClearFlag\":0,\n" + + " \"SigningPubKey\" : \"02356E89059A75438887F9FEE2056A2890DB82A68353BE9C0C0C8F89C0018B37FC\",\n" + + " \"NFTokenMinter\" : \"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn\",\n" + + " \"EmailHash\":\"f9879d71855b5ff21e4963273a886bfc\"\n" + + "}"; + + assertCanSerializeAndDeserialize(accountSet, json); + } } diff --git a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AccountSetIT.java b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AccountSetIT.java index 7124e1825..0ea468489 100644 --- a/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AccountSetIT.java +++ b/xrpl4j-integration-tests/src/test/java/org/xrpl/xrpl4j/tests/AccountSetIT.java @@ -33,6 +33,7 @@ import org.xrpl.xrpl4j.model.client.fees.FeeResult; import org.xrpl.xrpl4j.model.client.fees.FeeUtils; import org.xrpl.xrpl4j.model.client.transactions.SubmitResult; +import org.xrpl.xrpl4j.model.client.transactions.TransactionResult; import org.xrpl.xrpl4j.model.flags.AccountRootFlags; import org.xrpl.xrpl4j.model.flags.AccountSetTransactionFlags; import org.xrpl.xrpl4j.model.transactions.AccountSet; @@ -343,6 +344,46 @@ void disableMasterFailsWithNoSignerList() throws JsonRpcClientErrorException, Js logger.info("AccountSet SetFlag transaction failed successfully:"); } + @Test + void submitAndRetrieveAccountSetWithZeroClearFlagAndSetFlag() + throws JsonRpcClientErrorException, JsonProcessingException { + KeyPair keyPair = constructRandomAccount(); + + /////////////////////// + // Get validated account info and validate account state + AccountInfoResult accountInfo = this.scanForResult( + () -> this.getValidatedAccountInfo(keyPair.publicKey().deriveAddress()) + ); + + FeeResult feeResult = xrplClient.fee(); + AccountSet accountSet = AccountSet.builder() + .account(keyPair.publicKey().deriveAddress()) + .fee(FeeUtils.computeNetworkFees(feeResult).recommendedFee()) + .sequence(accountInfo.accountData().sequence()) + .setFlag(AccountSetFlag.NONE) + .clearFlag(AccountSetFlag.NONE) + .signingPublicKey(keyPair.publicKey()) + .build(); + + SingleSignedTransaction signedAccountSet = signatureService.sign( + keyPair.privateKey(), accountSet + ); + SubmitResult response = xrplClient.submit(signedAccountSet); + + assertThat(response.engineResult()).isEqualTo("tesSUCCESS"); + assertThat(signedAccountSet.hash()).isEqualTo(response.transactionResult().hash()); + logger.info( + "AccountSet transaction successful: https://testnet.xrpl.org/transactions/" + response.transactionResult().hash() + ); + + TransactionResult accountSetTransactionResult = this.scanForResult(() -> + this.getValidatedTransaction(signedAccountSet.hash(), AccountSet.class) + ); + + assertThat(accountSetTransactionResult.transaction().setFlag()).isNotEmpty().get().isEqualTo(AccountSetFlag.NONE); + assertThat(accountSetTransactionResult.transaction().clearFlag()).isNotEmpty().get().isEqualTo(AccountSetFlag.NONE); + } + ////////////////////// // Test Helpers //////////////////////