From 3df5a2a9ae0b0eeeed9d7a8eae9942766593c471 Mon Sep 17 00:00:00 2001 From: Joseph Sinclair <121976561+jsync-swirlds@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:04:26 -0700 Subject: [PATCH] feat: Add explicit `TokenType` to `SingleTransactionRecord`. (#10827) Signed-off-by: Joseph Sinclair --- .../app/state/SingleTransactionRecord.java | 9 +++- .../SingleTransactionRecordBuilderImpl.java | 13 +++++- .../recordcache/RecordCacheImplTest.java | 46 ++++++++++++------- .../handle/record/RecordTestData.java | 10 ++-- .../handlers/NetworkAdminHandlerTestBase.java | 4 +- .../handlers/TokenAccountWipeHandler.java | 1 + .../token/impl/handlers/TokenBurnHandler.java | 6 ++- .../impl/handlers/TokenCreateHandler.java | 1 + .../impl/handlers/TokenDeleteHandler.java | 4 ++ .../TokenFeeScheduleUpdateHandler.java | 4 ++ .../token/impl/handlers/TokenMintHandler.java | 7 +-- .../impl/handlers/TokenPauseHandler.java | 13 ++++-- .../impl/handlers/TokenUnpauseHandler.java | 13 ++++-- .../impl/handlers/TokenUpdateHandler.java | 1 + .../handlers/TokenAccountWipeHandlerTest.java | 10 ++++ .../test/handlers/TokenDeleteHandlerTest.java | 3 ++ .../TokenFeeScheduleUpdateHandlerTest.java | 6 +++ .../test/handlers/TokenPauseHandlerTest.java | 6 +++ .../handlers/TokenUnpauseHandlerTest.java | 6 +++ .../test/handlers/TokenUpdateHandlerTest.java | 10 ++-- .../TokenAccountWipeRecordBuilder.java | 3 +- .../token/records/TokenBaseRecordBuilder.java | 31 +++++++++++++ .../token/records/TokenBurnRecordBuilder.java | 3 +- .../records/TokenCreateRecordBuilder.java | 5 +- .../token/records/TokenMintRecordBuilder.java | 3 +- .../records/TokenUpdateRecordBuilder.java | 2 +- 26 files changed, 165 insertions(+), 55 deletions(-) create mode 100644 hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenBaseRecordBuilder.java diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/state/SingleTransactionRecord.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/state/SingleTransactionRecord.java index d4d8aa127d86..315a3f393238 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/state/SingleTransactionRecord.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/state/SingleTransactionRecord.java @@ -18,10 +18,12 @@ import static java.util.Objects.requireNonNull; +import com.hedera.hapi.node.base.TokenType; import com.hedera.hapi.node.base.Transaction; import com.hedera.hapi.node.transaction.TransactionRecord; import com.hedera.hapi.streams.TransactionSidecarRecord; import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.Nullable; import java.util.List; /** @@ -30,10 +32,15 @@ public record SingleTransactionRecord( @NonNull Transaction transaction, @NonNull TransactionRecord transactionRecord, - @NonNull List transactionSidecarRecords) { + @NonNull List transactionSidecarRecords, + @NonNull TransactionOutputs transactionOutputs) { public SingleTransactionRecord { requireNonNull(transaction, "transaction must not be null"); requireNonNull(transactionRecord, "record must not be null"); requireNonNull(transactionSidecarRecords, "transactionSidecarRecords must not be null"); + requireNonNull(transactionOutputs, "transactionOutputs must not be null"); } + + // This is used by BlockStream, and is not serialized. + public record TransactionOutputs(@Nullable TokenType tokenType) {} } diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/record/SingleTransactionRecordBuilderImpl.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/record/SingleTransactionRecordBuilderImpl.java index 47108635e43c..e0f8040f9fd3 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/record/SingleTransactionRecordBuilderImpl.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/record/SingleTransactionRecordBuilderImpl.java @@ -30,6 +30,7 @@ import com.hedera.hapi.node.base.TokenAssociation; import com.hedera.hapi.node.base.TokenID; import com.hedera.hapi.node.base.TokenTransferList; +import com.hedera.hapi.node.base.TokenType; import com.hedera.hapi.node.base.TopicID; import com.hedera.hapi.node.base.Transaction; import com.hedera.hapi.node.base.TransactionID; @@ -73,6 +74,7 @@ import com.hedera.node.app.spi.workflows.record.ExternalizedRecordCustomizer; import com.hedera.node.app.spi.workflows.record.SingleTransactionRecordBuilder; import com.hedera.node.app.state.SingleTransactionRecord; +import com.hedera.node.app.state.SingleTransactionRecord.TransactionOutputs; import com.hedera.pbj.runtime.OneOf; import com.hedera.pbj.runtime.io.buffer.Bytes; import com.swirlds.common.crypto.DigestType; @@ -177,6 +179,7 @@ public class SingleTransactionRecordBuilderImpl private final ExternalizedRecordCustomizer customizer; private TokenID tokenID; + private TokenType tokenType; /** * Possible behavior of a {@link SingleTransactionRecord} when a parent transaction fails, @@ -309,7 +312,8 @@ public SingleTransactionRecord build() { // Log end of user transaction to transaction state log logEndTransactionRecord(transactionID, transactionRecord); - return new SingleTransactionRecord(transaction, transactionRecord, transactionSidecarRecords); + return new SingleTransactionRecord( + transaction, transactionRecord, transactionSidecarRecords, new TransactionOutputs(tokenType)); } public void nullOutSideEffectFields() { @@ -562,6 +566,13 @@ public SingleTransactionRecordBuilderImpl addTokenTransferList(@NonNull final To return this; } + @Override + @NonNull + public SingleTransactionRecordBuilderImpl tokenType(final @NonNull TokenType tokenType) { + this.tokenType = requireNonNull(tokenType); + return this; + } + /** * Sets the scheduleRef. * diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/state/recordcache/RecordCacheImplTest.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/state/recordcache/RecordCacheImplTest.java index 54420451525a..48ce835aaabe 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/state/recordcache/RecordCacheImplTest.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/state/recordcache/RecordCacheImplTest.java @@ -32,6 +32,7 @@ import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.base.ResponseCodeEnum; import com.hedera.hapi.node.base.Timestamp; +import com.hedera.hapi.node.base.TokenType; import com.hedera.hapi.node.base.TransactionID; import com.hedera.hapi.node.state.recordcache.TransactionRecordEntry; import com.hedera.hapi.node.transaction.TransactionReceipt; @@ -46,6 +47,7 @@ import com.hedera.node.app.spi.state.WritableQueueState; import com.hedera.node.app.state.DeduplicationCache; import com.hedera.node.app.state.SingleTransactionRecord; +import com.hedera.node.app.state.SingleTransactionRecord.TransactionOutputs; import com.hedera.node.app.state.WorkingStateAccessor; import com.hedera.node.config.ConfigProvider; import com.hedera.node.config.VersionedConfiguration; @@ -78,6 +80,7 @@ final class RecordCacheImplTest extends AppTestBase { TransactionReceipt.newBuilder().status(UNKNOWN).build(); private static final AccountID PAYER_ACCOUNT_ID = AccountID.newBuilder().accountNum(1001).build(); + private static final TransactionOutputs SIMPLE_OUTPUT = new TransactionOutputs(TokenType.FUNGIBLE_COMMON); private DeduplicationCache dedupeCache; @@ -438,7 +441,7 @@ final var record = TransactionRecord.newBuilder() .build(); // When the record is added to the cache - cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); + cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); // Then we can query for the receipt by transaction ID assertThat(getReceipt(cache, txId)).isEqualTo(receipt); @@ -459,7 +462,7 @@ final var record = TransactionRecord.newBuilder() .build(); // When the record is added to the cache - cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); + cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); // Then we can query for the receipt by transaction ID assertThat(getReceipts(cache, txId)).containsExactly(receipt); @@ -480,7 +483,7 @@ final var record = TransactionRecord.newBuilder() .build(); // When the record is added to the cache - cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); + cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); // Then we can query for the receipt by transaction ID assertThat(getReceipts(cache, PAYER_ACCOUNT_ID)).containsExactly(receipt); @@ -507,7 +510,10 @@ final var record = TransactionRecord.newBuilder() .transactionID(txId) .receipt(receipt) .build(); - cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); + cache.add( + 0, + PAYER_ACCOUNT_ID, + List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); } } @@ -599,7 +605,7 @@ final var record = TransactionRecord.newBuilder() .build(); // When the record is added to the cache - cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); + cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); // Then we can query for the receipt by transaction ID assertThat(getRecord(cache, txId)).isEqualTo(record); @@ -620,7 +626,7 @@ final var record = TransactionRecord.newBuilder() .build(); // When the record is added to the cache - cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); + cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); // Then we can query for the receipt by transaction ID assertThat(getRecords(cache, txId)).containsExactly(record); @@ -646,10 +652,16 @@ void unclassifiableStatusIsNotPriority() { .build(); // When the unclassifiable record is added to the cache - cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, unclassifiableRecord, List.of()))); + cache.add( + 0, + PAYER_ACCOUNT_ID, + List.of(new SingleTransactionRecord(tx, unclassifiableRecord, List.of(), SIMPLE_OUTPUT))); // It does not prevent a "good" record from using this transaction id assertThat(cache.hasDuplicate(txId, 0L)).isEqualTo(NO_DUPLICATE); - cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, classifiableRecord, List.of()))); + cache.add( + 0, + PAYER_ACCOUNT_ID, + List.of(new SingleTransactionRecord(tx, classifiableRecord, List.of(), SIMPLE_OUTPUT))); // And we get the success record from userTransactionRecord() assertThat(cache.getHistory(txId)).isNotNull(); @@ -673,7 +685,7 @@ final var record = TransactionRecord.newBuilder() .build(); // When the record is added to the cache - cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); + cache.add(0, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); // Then we can query for the receipt by transaction ID assertThat(cache.getRecords(PAYER_ACCOUNT_ID)).containsExactly(record); @@ -731,7 +743,7 @@ final var record = TransactionRecord.newBuilder() .build(); // When the record is added to the cache - cache.add(1L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); + cache.add(1L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); // Then we can check for a duplicate by transaction ID assertThat(cache.hasDuplicate(txId, 2L)).isEqualTo(OTHER_NODE); @@ -751,7 +763,7 @@ final var record = TransactionRecord.newBuilder() .build(); // When the record is added to the cache - cache.add(1L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); + cache.add(1L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); // Then we can check for a duplicate by transaction ID assertThat(cache.hasDuplicate(txId, 1L)).isEqualTo(SAME_NODE); @@ -771,9 +783,9 @@ final var record = TransactionRecord.newBuilder() .build(); // When the record is added to the cache - cache.add(1L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); - cache.add(2L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); - cache.add(3L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); + cache.add(1L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); + cache.add(2L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); + cache.add(3L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); // Then we can check for a duplicate by transaction ID assertThat(cache.hasDuplicate(txId, 11L)).isEqualTo(OTHER_NODE); @@ -794,9 +806,9 @@ final var record = TransactionRecord.newBuilder() .build(); // When the record is added to the cache - cache.add(1L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); - cache.add(2L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); - cache.add(3L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of()))); + cache.add(1L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); + cache.add(2L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); + cache.add(3L, PAYER_ACCOUNT_ID, List.of(new SingleTransactionRecord(tx, record, List.of(), SIMPLE_OUTPUT))); // Then we can check for a duplicate by transaction ID assertThat(cache.hasDuplicate(txId, currentNodeId)).isEqualTo(SAME_NODE); diff --git a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/RecordTestData.java b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/RecordTestData.java index c6b86040e868..e48ba6ce9f09 100644 --- a/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/RecordTestData.java +++ b/hedera-node/hedera-app/src/test/java/com/hedera/node/app/workflows/handle/record/RecordTestData.java @@ -20,6 +20,7 @@ import com.hedera.hapi.node.base.SemanticVersion; import com.hedera.hapi.node.base.Timestamp; +import com.hedera.hapi.node.base.TokenType; import com.hedera.hapi.node.base.Transaction; import com.hedera.hapi.node.transaction.SignedTransaction; import com.hedera.hapi.node.transaction.TransactionBody; @@ -31,6 +32,7 @@ import com.hedera.hapi.streams.TransactionSidecarRecord; import com.hedera.node.app.records.impl.producers.formats.v6.BlockRecordFormatV6; import com.hedera.node.app.state.SingleTransactionRecord; +import com.hedera.node.app.state.SingleTransactionRecord.TransactionOutputs; import com.hedera.pbj.runtime.io.buffer.BufferedData; import com.hedera.pbj.runtime.io.buffer.Bytes; import com.hedera.pbj.runtime.io.stream.ReadableStreamingData; @@ -81,6 +83,8 @@ public class RecordTestData { new boolean[] {false, true, true, true, false, true, false, false, true}; // block seconds 24, 26, 28, 30, 32, 34, 36, 38, 40 + /** Transaction Outputs data */ + private static final TransactionOutputs SIMPLE_OUTPUT = new TransactionOutputs(TokenType.FUNGIBLE_COMMON); /** Test Signer for signing record stream files */ public static final Signer SIGNER; /** Test user public key */ @@ -104,8 +108,8 @@ public class RecordTestData { final RecordStreamFile recordStreamFile = RecordStreamFile.JSON.parse(new ReadableStreamingData(Files.newInputStream(jsonPath))); final List realRecordStreamItems = recordStreamFile.recordStreamItems().stream() - .map(item -> - new SingleTransactionRecord(item.transaction(), item.record(), Collections.emptyList())) + .map(item -> new SingleTransactionRecord( + item.transaction(), item.record(), Collections.emptyList(), SIMPLE_OUTPUT)) .toList(); // load real sidecar items from a JSON resource file final Path sidecarPath = Path.of(RecordTestData.class @@ -240,6 +244,6 @@ private static SingleTransactionRecord changeTransactionConsensusTimeAndGenerate } } // return new SingleTransactionRecord - return new SingleTransactionRecord(newTransaction, newTransactionRecord, sidecarItems); + return new SingleTransactionRecord(newTransaction, newTransactionRecord, sidecarItems, SIMPLE_OUTPUT); } } diff --git a/hedera-node/hedera-network-admin-service-impl/src/test/java/com/hedera/node/app/service/networkadmin/impl/test/handlers/NetworkAdminHandlerTestBase.java b/hedera-node/hedera-network-admin-service-impl/src/test/java/com/hedera/node/app/service/networkadmin/impl/test/handlers/NetworkAdminHandlerTestBase.java index 3d156e423241..7c1d53c7142c 100644 --- a/hedera-node/hedera-network-admin-service-impl/src/test/java/com/hedera/node/app/service/networkadmin/impl/test/handlers/NetworkAdminHandlerTestBase.java +++ b/hedera-node/hedera-network-admin-service-impl/src/test/java/com/hedera/node/app/service/networkadmin/impl/test/handlers/NetworkAdminHandlerTestBase.java @@ -54,6 +54,7 @@ import com.hedera.node.app.spi.state.ReadableStates; import com.hedera.node.app.state.DeduplicationCache; import com.hedera.node.app.state.SingleTransactionRecord; +import com.hedera.node.app.state.SingleTransactionRecord.TransactionOutputs; import com.hedera.node.app.state.WorkingStateAccessor; import com.hedera.node.app.state.recordcache.DeduplicationCacheImpl; import com.hedera.node.app.state.recordcache.RecordCacheImpl; @@ -289,7 +290,8 @@ private void givenRecordCacheState() { } private SingleTransactionRecord singleTransactionRecord(TransactionRecord record) { - return new SingleTransactionRecord(Transaction.DEFAULT, record, List.of()); + return new SingleTransactionRecord( + Transaction.DEFAULT, record, List.of(), new TransactionOutputs(TokenType.FUNGIBLE_COMMON)); } protected MapReadableKVState readableAccountState() { diff --git a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenAccountWipeHandler.java b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenAccountWipeHandler.java index b9cfddb62976..2ab4d8da2788 100644 --- a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenAccountWipeHandler.java +++ b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenAccountWipeHandler.java @@ -199,6 +199,7 @@ public void handle(@NonNull final HandleContext context) throws HandleException final var record = context.recordBuilder(TokenAccountWipeRecordBuilder.class); // Set newTotalSupply in record record.newTotalSupply(newTotalSupply); + record.tokenType(token.tokenType()); } @NonNull diff --git a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenBurnHandler.java b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenBurnHandler.java index 1f897b085001..cd29d66f3e25 100644 --- a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenBurnHandler.java +++ b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenBurnHandler.java @@ -121,6 +121,7 @@ public void handle(@NonNull final HandleContext context) throws HandleException validateTrue(treasuryRel.kycGranted(), ACCOUNT_KYC_NOT_GRANTED_FOR_TOKEN); } + TokenBurnRecordBuilder record = context.recordBuilder(TokenBurnRecordBuilder.class); if (token.tokenType() == TokenType.FUNGIBLE_COMMON) { validateTrue(fungibleBurnCount >= 0 && nftSerialNums.isEmpty(), INVALID_TOKEN_BURN_AMOUNT); final var newTotalSupply = changeSupply( @@ -131,7 +132,7 @@ public void handle(@NonNull final HandleContext context) throws HandleException accountStore, tokenStore, tokenRelStore); - context.recordBuilder(TokenBurnRecordBuilder.class).newTotalSupply(newTotalSupply); + record.newTotalSupply(newTotalSupply); } else { validateTrue(!nftSerialNums.isEmpty(), INVALID_TOKEN_BURN_METADATA); @@ -158,8 +159,9 @@ public void handle(@NonNull final HandleContext context) throws HandleException // Remove the nft objects nftSerialNums.forEach(serialNum -> nftStore.remove(tokenId, serialNum)); - context.recordBuilder(TokenBurnRecordBuilder.class).newTotalSupply(newTotalSupply); + record.newTotalSupply(newTotalSupply); } + record.tokenType(token.tokenType()); } @NonNull diff --git a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenCreateHandler.java b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenCreateHandler.java index ca9e1687ed12..53ed8710b94e 100644 --- a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenCreateHandler.java +++ b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenCreateHandler.java @@ -168,6 +168,7 @@ public void handle(@NonNull final HandleContext context) { // Update record with newly created token id recordBuilder.tokenID(newTokenId); + recordBuilder.tokenType(newToken.tokenType()); } /** diff --git a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenDeleteHandler.java b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenDeleteHandler.java index 6a2a3577e4b4..0dbb615981eb 100644 --- a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenDeleteHandler.java +++ b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenDeleteHandler.java @@ -34,6 +34,7 @@ import com.hedera.node.app.service.token.impl.WritableAccountStore; import com.hedera.node.app.service.token.impl.WritableTokenStore; import com.hedera.node.app.service.token.impl.util.TokenHandlerHelper; +import com.hedera.node.app.service.token.records.TokenBaseRecordBuilder; import com.hedera.node.app.spi.fees.FeeContext; import com.hedera.node.app.spi.fees.Fees; import com.hedera.node.app.spi.workflows.HandleContext; @@ -94,6 +95,9 @@ public void handle(@NonNull final HandleContext context) throws HandleException .numberTreasuryTitles(account.numberTreasuryTitles() - 1) .build(); accountStore.put(updatedAccount); + + final var record = context.recordBuilder(TokenBaseRecordBuilder.class); + record.tokenType(updatedToken.tokenType()); } @NonNull diff --git a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenFeeScheduleUpdateHandler.java b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenFeeScheduleUpdateHandler.java index 3448098a6299..1dbed528b419 100644 --- a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenFeeScheduleUpdateHandler.java +++ b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenFeeScheduleUpdateHandler.java @@ -42,6 +42,7 @@ import com.hedera.node.app.service.token.impl.WritableTokenStore; import com.hedera.node.app.service.token.impl.util.TokenHandlerHelper; import com.hedera.node.app.service.token.impl.validators.CustomFeesValidator; +import com.hedera.node.app.service.token.records.TokenBaseRecordBuilder; import com.hedera.node.app.spi.fees.FeeContext; import com.hedera.node.app.spi.fees.Fees; import com.hedera.node.app.spi.workflows.HandleContext; @@ -123,6 +124,9 @@ public void handle(@NonNull final HandleContext context) { final var copy = token.copyBuilder().customFees(op.customFees()); // add token to the modifications map tokenStore.put(copy.build()); + + final var record = context.recordBuilder(TokenBaseRecordBuilder.class); + record.tokenType(token.tokenType()); } /** diff --git a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenMintHandler.java b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenMintHandler.java index fe9fbbe640fb..f4b41bf77f12 100644 --- a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenMintHandler.java +++ b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenMintHandler.java @@ -135,14 +135,12 @@ public void handle(@NonNull final HandleContext context) throws HandleException validateTrue(treasuryRel.kycGranted(), ACCOUNT_KYC_NOT_GRANTED_FOR_TOKEN); } + final var recordBuilder = context.recordBuilder(TokenMintRecordBuilder.class); if (token.tokenType() == TokenType.FUNGIBLE_COMMON) { - validateTrue(op.amount() >= 0 && op.metadata().isEmpty(), INVALID_TOKEN_MINT_AMOUNT); // we need to know if treasury mint while creation to ignore supply key exist or not. long newTotalSupply = mintFungible(token, treasuryRel, op.amount(), accountStore, tokenStore, tokenRelStore); - final var recordBuilder = context.recordBuilder(TokenMintRecordBuilder.class); - recordBuilder.newTotalSupply(newTotalSupply); } else { // get the config needed for validation @@ -163,14 +161,13 @@ public void handle(@NonNull final HandleContext context) throws HandleException tokenStore, tokenRelStore, nftStore); - final var recordBuilder = context.recordBuilder(TokenMintRecordBuilder.class); - recordBuilder.newTotalSupply(tokenStore.get(tokenId).totalSupply()); recordBuilder.serialNumbers(mintedSerials); // TODO: Need to build transfer ownership from list to transfer NFT to treasury // This should probably be done in finalize method on token service which constructs the // transfer list looking at state } + recordBuilder.tokenType(token.tokenType()); } /** diff --git a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenPauseHandler.java b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenPauseHandler.java index 837092153d36..dd6d9b89c446 100644 --- a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenPauseHandler.java +++ b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenPauseHandler.java @@ -27,6 +27,7 @@ import com.hedera.hapi.node.base.TokenID; import com.hedera.node.app.service.token.ReadableTokenStore; import com.hedera.node.app.service.token.impl.WritableTokenStore; +import com.hedera.node.app.service.token.records.TokenBaseRecordBuilder; import com.hedera.node.app.spi.fees.FeeContext; import com.hedera.node.app.spi.fees.Fees; import com.hedera.node.app.spi.workflows.HandleContext; @@ -66,15 +67,15 @@ public void preHandle(@NonNull final PreHandleContext context) throws PreCheckEx /** * This method is called during the handle workflow. It executes the actual transaction. * - * @param handleContext the {@link HandleContext} for the active transaction + * @param context the {@link HandleContext} for the active transaction * @throws NullPointerException if one of the arguments is {@code null} */ @Override - public void handle(@NonNull final HandleContext handleContext) { - requireNonNull(handleContext); + public void handle(@NonNull final HandleContext context) { + requireNonNull(context); - final var op = handleContext.body().tokenPause(); - final var tokenStore = handleContext.writableStore(WritableTokenStore.class); + final var op = context.body().tokenPause(); + final var tokenStore = context.writableStore(WritableTokenStore.class); var token = tokenStore.get(op.tokenOrElse(TokenID.DEFAULT)); validateTrue(token != null, INVALID_TOKEN_ID); validateTrue(token.hasPauseKey(), TOKEN_HAS_NO_PAUSE_KEY); @@ -82,6 +83,8 @@ public void handle(@NonNull final HandleContext handleContext) { final var copyBuilder = token.copyBuilder(); copyBuilder.paused(true); tokenStore.put(copyBuilder.build()); + final var record = context.recordBuilder(TokenBaseRecordBuilder.class); + record.tokenType(token.tokenType()); } /** diff --git a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenUnpauseHandler.java b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenUnpauseHandler.java index dc4f135dc2df..6d45096f3c00 100644 --- a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenUnpauseHandler.java +++ b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenUnpauseHandler.java @@ -27,6 +27,7 @@ import com.hedera.hapi.node.base.TokenID; import com.hedera.node.app.service.token.ReadableTokenStore; import com.hedera.node.app.service.token.impl.WritableTokenStore; +import com.hedera.node.app.service.token.records.TokenBaseRecordBuilder; import com.hedera.node.app.spi.fees.FeeContext; import com.hedera.node.app.spi.fees.Fees; import com.hedera.node.app.spi.workflows.HandleContext; @@ -67,15 +68,15 @@ public void preHandle(@NonNull final PreHandleContext context) throws PreCheckEx /** * This method is called during the handle workflow. It executes the actual transaction. * - * @param handleContext the {@link HandleContext} for the active transaction + * @param context the {@link HandleContext} for the active transaction * @throws NullPointerException if one of the arguments is {@code null} */ @Override - public void handle(@NonNull final HandleContext handleContext) { - requireNonNull(handleContext); + public void handle(@NonNull final HandleContext context) { + requireNonNull(context); - final var op = handleContext.body().tokenUnpause(); - final var tokenStore = handleContext.writableStore(WritableTokenStore.class); + final var op = context.body().tokenUnpause(); + final var tokenStore = context.writableStore(WritableTokenStore.class); var token = tokenStore.get(op.tokenOrElse(TokenID.DEFAULT)); validateTrue(token != null, INVALID_TOKEN_ID); validateTrue(token.hasPauseKey(), TOKEN_HAS_NO_PAUSE_KEY); @@ -83,6 +84,8 @@ public void handle(@NonNull final HandleContext handleContext) { final var copyBuilder = token.copyBuilder(); copyBuilder.paused(false); tokenStore.put(copyBuilder.build()); + final var record = context.recordBuilder(TokenBaseRecordBuilder.class); + record.tokenType(token.tokenType()); } /** diff --git a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenUpdateHandler.java b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenUpdateHandler.java index d8c5a3bc1e22..eed0f22b0780 100644 --- a/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenUpdateHandler.java +++ b/hedera-node/hedera-token-service-impl/src/main/java/com/hedera/node/app/service/token/impl/handlers/TokenUpdateHandler.java @@ -178,6 +178,7 @@ public void handle(@NonNull final HandleContext context) throws HandleException final var tokenBuilder = customizeToken(token, resolvedExpiry, op); tokenStore.put(tokenBuilder.build()); + recordBuilder.tokenType(token.tokenType()); } /** diff --git a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenAccountWipeHandlerTest.java b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenAccountWipeHandlerTest.java index db9ec0e5a180..491fb98a537c 100644 --- a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenAccountWipeHandlerTest.java +++ b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenAccountWipeHandlerTest.java @@ -77,6 +77,7 @@ import com.hedera.node.app.service.token.impl.test.handlers.util.ParityTestBase; import com.hedera.node.app.service.token.impl.validators.TokenSupplyChangeOpsValidator; import com.hedera.node.app.service.token.records.TokenAccountWipeRecordBuilder; +import com.hedera.node.app.service.token.records.TokenBaseRecordBuilder; import com.hedera.node.app.spi.fixtures.workflows.FakePreHandleContext; import com.hedera.node.app.spi.validation.ExpiryValidator; import com.hedera.node.app.spi.workflows.HandleContext; @@ -85,6 +86,7 @@ import com.hedera.node.app.spi.workflows.record.SingleTransactionRecordBuilder; import com.hedera.node.config.testfixtures.HederaTestConfigBuilder; import com.swirlds.config.api.Configuration; +import edu.umd.cs.findbugs.annotations.NonNull; import org.assertj.core.api.Assertions; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeEach; @@ -113,6 +115,7 @@ public void setUp() { .getOrCreateConfig(); recordBuilder = new TokenAccountWipeRecordBuilder() { private long newTotalSupply; + private TokenType tokenType; @NotNull @Override @@ -142,6 +145,13 @@ public TokenAccountWipeRecordBuilder newTotalSupply(final long supply) { return this; } + @NotNull + @Override + public TokenBaseRecordBuilder tokenType(final @NonNull TokenType tokenType) { + this.tokenType = tokenType; + return this; + } + @NotNull @Override public ResponseCodeEnum status() { diff --git a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenDeleteHandlerTest.java b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenDeleteHandlerTest.java index 19d734958bd6..4ec30da6eb71 100644 --- a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenDeleteHandlerTest.java +++ b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenDeleteHandlerTest.java @@ -29,6 +29,7 @@ import static com.hedera.test.factories.scenarios.TxnHandlingScenario.TOKEN_ADMIN_KT; import static com.hedera.test.factories.txns.SignedTxnFactory.DEFAULT_PAYER_KT; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; @@ -47,6 +48,7 @@ import com.hedera.node.app.service.token.impl.handlers.TokenDeleteHandler; import com.hedera.node.app.service.token.impl.test.handlers.util.ParityTestBase; import com.hedera.node.app.service.token.impl.test.util.SigReqAdapterUtils; +import com.hedera.node.app.service.token.records.TokenBaseRecordBuilder; import com.hedera.node.app.spi.fixtures.workflows.FakePreHandleContext; import com.hedera.node.app.spi.workflows.HandleContext; import com.hedera.node.app.spi.workflows.HandleException; @@ -214,6 +216,7 @@ private HandleContext mockContext() { given(context.writableStore(WritableTokenStore.class)).willReturn(writableTokenStore); given(context.writableStore(WritableAccountStore.class)).willReturn(writableAccountStore); + given(context.recordBuilder(any())).willReturn(mock(TokenBaseRecordBuilder.class)); return context; } diff --git a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenFeeScheduleUpdateHandlerTest.java b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenFeeScheduleUpdateHandlerTest.java index ae516d997f8f..789495bf8728 100644 --- a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenFeeScheduleUpdateHandlerTest.java +++ b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenFeeScheduleUpdateHandlerTest.java @@ -24,6 +24,7 @@ import static com.hedera.node.app.spi.fixtures.workflows.ExceptionConditions.responseCode; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mock.Strictness.LENIENT; @@ -38,6 +39,7 @@ import com.hedera.node.app.service.token.impl.handlers.TokenFeeScheduleUpdateHandler; import com.hedera.node.app.service.token.impl.test.handlers.util.CryptoTokenHandlerTestBase; import com.hedera.node.app.service.token.impl.validators.CustomFeesValidator; +import com.hedera.node.app.service.token.records.TokenBaseRecordBuilder; import com.hedera.node.app.spi.fixtures.state.MapWritableKVState; import com.hedera.node.app.spi.workflows.HandleContext; import com.hedera.node.app.spi.workflows.HandleException; @@ -65,6 +67,9 @@ class TokenFeeScheduleUpdateHandlerTest extends CryptoTokenHandlerTestBase { @Mock private PreHandleContext preHandleContext; + @Mock(strictness = LENIENT) + private TokenBaseRecordBuilder recordBuilder; + @BeforeEach void setup() { super.setUp(); @@ -79,6 +84,7 @@ void setup() { given(context.readableStore(ReadableAccountStore.class)).willReturn(readableAccountStore); given(context.readableStore(ReadableTokenRelationStore.class)).willReturn(readableTokenRelStore); given(context.writableStore(WritableTokenStore.class)).willReturn(writableTokenStore); + given(context.recordBuilder(any())).willReturn(recordBuilder); } @Test diff --git a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenPauseHandlerTest.java b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenPauseHandlerTest.java index 46e84f2e3d27..7d0bbcbcc288 100644 --- a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenPauseHandlerTest.java +++ b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenPauseHandlerTest.java @@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mock.Strictness.LENIENT; @@ -39,6 +40,7 @@ import com.hedera.node.app.service.token.impl.WritableTokenStore; import com.hedera.node.app.service.token.impl.handlers.TokenPauseHandler; import com.hedera.node.app.service.token.impl.test.handlers.util.TokenHandlerTestBase; +import com.hedera.node.app.service.token.records.TokenBaseRecordBuilder; import com.hedera.node.app.spi.fixtures.state.MapReadableKVState; import com.hedera.node.app.spi.fixtures.workflows.FakePreHandleContext; import com.hedera.node.app.spi.workflows.HandleContext; @@ -65,6 +67,9 @@ class TokenPauseHandlerTest extends TokenHandlerTestBase { @Mock(strictness = LENIENT) private HandleContext handleContext; + @Mock(strictness = LENIENT) + private TokenBaseRecordBuilder recordBuilder; + @BeforeEach void setUp() throws PreCheckException { given(accountStore.getAccountById(AccountID.newBuilder().accountNum(3L).build())) @@ -76,6 +81,7 @@ void setUp() throws PreCheckException { refreshStoresWithCurrentTokenInWritable(); preHandleContext = new FakePreHandleContext(accountStore, tokenPauseTxn); given(handleContext.writableStore(WritableTokenStore.class)).willReturn(writableTokenStore); + given(handleContext.recordBuilder(any())).willReturn(recordBuilder); } @Test diff --git a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenUnpauseHandlerTest.java b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenUnpauseHandlerTest.java index fadf11052745..6a64cb3659cb 100644 --- a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenUnpauseHandlerTest.java +++ b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenUnpauseHandlerTest.java @@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mock.Strictness.LENIENT; @@ -38,6 +39,7 @@ import com.hedera.node.app.service.token.impl.WritableTokenStore; import com.hedera.node.app.service.token.impl.handlers.TokenUnpauseHandler; import com.hedera.node.app.service.token.impl.test.handlers.util.TokenHandlerTestBase; +import com.hedera.node.app.service.token.records.TokenBaseRecordBuilder; import com.hedera.node.app.spi.fixtures.state.MapReadableKVState; import com.hedera.node.app.spi.fixtures.workflows.FakePreHandleContext; import com.hedera.node.app.spi.workflows.HandleContext; @@ -64,6 +66,9 @@ class TokenUnpauseHandlerTest extends TokenHandlerTestBase { @Mock(strictness = LENIENT) private HandleContext handleContext; + @Mock(strictness = LENIENT) + private TokenBaseRecordBuilder recordBuilder; + @BeforeEach void setUp() throws PreCheckException { given(accountStore.getAccountById(payerId)).willReturn(account); @@ -73,6 +78,7 @@ void setUp() throws PreCheckException { refreshStoresWithCurrentTokenInWritable(); preHandleContext = new FakePreHandleContext(accountStore, tokenUnpauseTxn); given(handleContext.writableStore(WritableTokenStore.class)).willReturn(writableTokenStore); + given(handleContext.recordBuilder(any())).willReturn(recordBuilder); } @Test diff --git a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenUpdateHandlerTest.java b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenUpdateHandlerTest.java index 4f6eaecf94fe..de17b75110db 100644 --- a/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenUpdateHandlerTest.java +++ b/hedera-node/hedera-token-service-impl/src/test/java/com/hedera/node/app/service/token/impl/test/handlers/TokenUpdateHandlerTest.java @@ -50,6 +50,7 @@ import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mock.Strictness.LENIENT; import static org.mockito.Mockito.verify; @@ -87,6 +88,7 @@ import com.hedera.node.config.ConfigProvider; import com.hedera.node.config.VersionedConfigImpl; import com.hedera.node.config.testfixtures.HederaTestConfigBuilder; +import java.time.Instant; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -111,13 +113,14 @@ class TokenUpdateHandlerTest extends CryptoTokenHandlerTestBase { @Mock(strictness = LENIENT) private GlobalDynamicProperties dynamicProperties; - @Mock + @Mock(strictness = LENIENT) private TokenUpdateRecordBuilder recordBuilder; private TransactionBody txn; private ExpiryValidator expiryValidator; private AttributeValidator attributeValidator; private TokenUpdateHandler subject; + private final Instant consensusNow = Instant.ofEpochSecond(1_234_567L); @BeforeEach public void setUp() { @@ -125,6 +128,7 @@ public void setUp() { refreshWritableStores(); final TokenUpdateValidator validator = new TokenUpdateValidator(new TokenAttributesValidator()); subject = new TokenUpdateHandler(validator); + given(handleContext.recordBuilder(any())).willReturn(recordBuilder); givenStoresAndConfig(handleContext); setUpTxnContext(); } @@ -380,7 +384,6 @@ void worksWithUnassociatedNewTreasuryIfAutoAssociationsAvailable() { .build()); given(handleContext.writableStore(WritableTokenRelationStore.class)).willReturn(writableTokenRelStore); given(handleContext.readableStore(ReadableTokenRelationStore.class)).willReturn(writableTokenRelStore); - given(handleContext.recordBuilder(TokenUpdateRecordBuilder.class)).willReturn(recordBuilder); assertThat(writableTokenRelStore.get(payerId, fungibleTokenId)).isNull(); final var token = readableTokenStore.get(fungibleTokenId); @@ -473,7 +476,6 @@ void worksWithUnassociatedNewTreasuryIfAutoAssociationsAvailableForNFT() { final var newTreasuryRel = writableTokenRelStore.get(payerId, nonFungibleTokenId); final var oldTreasuryRel = writableTokenRelStore.get(treasuryId, nonFungibleTokenId); - given(handleContext.recordBuilder(TokenUpdateRecordBuilder.class)).willReturn(recordBuilder); assertThat(newTreasuryRel).isNull(); assertThat(oldTreasuryRel.balance()).isEqualTo(1); @@ -792,7 +794,6 @@ void followsHappyPathWithNewTreasuryAndZeroBalanceOldTreasury() { given(handleContext.writableStore(WritableAccountStore.class)).willReturn(writableAccountStore); given(handleContext.readableStore(ReadableAccountStore.class)).willReturn(writableAccountStore); assertThat(writableTokenRelStore.get(payerId, fungibleTokenId)).isNull(); - given(handleContext.recordBuilder(TokenUpdateRecordBuilder.class)).willReturn(recordBuilder); assertThatNoException().isThrownBy(() -> subject.handle(handleContext)); @@ -845,7 +846,6 @@ void doesntGrantKycOrUnfreezeNewTreasuryIfNoKeyIsPresent() { .build()); given(handleContext.writableStore(WritableTokenStore.class)).willReturn(writableTokenStore); given(handleContext.readableStore(ReadableTokenStore.class)).willReturn(writableTokenStore); - given(handleContext.recordBuilder(TokenUpdateRecordBuilder.class)).willReturn(recordBuilder); assertThatNoException().isThrownBy(() -> subject.handle(handleContext)); diff --git a/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenAccountWipeRecordBuilder.java b/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenAccountWipeRecordBuilder.java index 8971988b3fb6..fe2eae6c6d9f 100644 --- a/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenAccountWipeRecordBuilder.java +++ b/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenAccountWipeRecordBuilder.java @@ -16,14 +16,13 @@ package com.hedera.node.app.service.token.records; -import com.hedera.node.app.spi.workflows.record.SingleTransactionRecordBuilder; import edu.umd.cs.findbugs.annotations.NonNull; /** * A {@code RecordBuilder} specialization for tracking the side effects of a {@code TokenWipe} * transaction. */ -public interface TokenAccountWipeRecordBuilder extends SingleTransactionRecordBuilder { +public interface TokenAccountWipeRecordBuilder extends TokenBaseRecordBuilder { /** * Gets the new total supply of a token diff --git a/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenBaseRecordBuilder.java b/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenBaseRecordBuilder.java new file mode 100644 index 000000000000..55b603449312 --- /dev/null +++ b/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenBaseRecordBuilder.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.node.app.service.token.records; + +import com.hedera.hapi.node.base.TokenType; +import com.hedera.node.app.spi.workflows.record.SingleTransactionRecordBuilder; +import edu.umd.cs.findbugs.annotations.NonNull; + +/** + * The base interface for Token Service record builders that record operations on Tokens. + */ +public interface TokenBaseRecordBuilder extends SingleTransactionRecordBuilder { + /** + * Sets the {@link TokenType} of the token the recorded transaction created or modified. + */ + TokenBaseRecordBuilder tokenType(final @NonNull TokenType tokenType); +} diff --git a/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenBurnRecordBuilder.java b/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenBurnRecordBuilder.java index cdb905fce3ab..75d06fe2ecbb 100644 --- a/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenBurnRecordBuilder.java +++ b/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenBurnRecordBuilder.java @@ -16,7 +16,6 @@ package com.hedera.node.app.service.token.records; -import com.hedera.node.app.spi.workflows.record.SingleTransactionRecordBuilder; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; @@ -24,7 +23,7 @@ * A {@code RecordBuilder} specialization for tracking the side effects of a {@code TokenBurn} * transaction. */ -public interface TokenBurnRecordBuilder extends SingleTransactionRecordBuilder { +public interface TokenBurnRecordBuilder extends TokenBaseRecordBuilder { /** * Gets the new total supply of a token diff --git a/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenCreateRecordBuilder.java b/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenCreateRecordBuilder.java index 4d0d00a7d9b2..9cbc59fa3c62 100644 --- a/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenCreateRecordBuilder.java +++ b/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenCreateRecordBuilder.java @@ -19,14 +19,13 @@ import com.hedera.hapi.node.base.AccountID; import com.hedera.hapi.node.base.TokenAssociation; import com.hedera.hapi.node.base.TokenID; -import com.hedera.node.app.spi.workflows.record.SingleTransactionRecordBuilder; import edu.umd.cs.findbugs.annotations.NonNull; /** * A {@code RecordBuilder} specialization for tracking the side effects of a {@code TokenCreate} * transaction. */ -public interface TokenCreateRecordBuilder extends SingleTransactionRecordBuilder { +public interface TokenCreateRecordBuilder extends TokenBaseRecordBuilder { /** * Tracks creation of a new token by number. Even if someday we support creating multiple * tokens within a smart contract call, we will still only need to track one created token @@ -46,5 +45,5 @@ public interface TokenCreateRecordBuilder extends SingleTransactionRecordBuilder * @param tokenAssociation the token association that is created by auto association * @return the builder */ - TokenUpdateRecordBuilder addAutomaticTokenAssociation(@NonNull final TokenAssociation tokenAssociation); + TokenCreateRecordBuilder addAutomaticTokenAssociation(@NonNull final TokenAssociation tokenAssociation); } diff --git a/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenMintRecordBuilder.java b/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenMintRecordBuilder.java index cdbf18314cee..0d4b68787e4c 100644 --- a/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenMintRecordBuilder.java +++ b/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenMintRecordBuilder.java @@ -16,7 +16,6 @@ package com.hedera.node.app.service.token.records; -import com.hedera.node.app.spi.workflows.record.SingleTransactionRecordBuilder; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.List; @@ -24,7 +23,7 @@ * A {@code RecordBuilder} specialization for tracking the side effects of a {@code CryptoCreate} * transaction. */ -public interface TokenMintRecordBuilder extends SingleTransactionRecordBuilder { +public interface TokenMintRecordBuilder extends TokenBaseRecordBuilder { /** * Tracks creation of a new account by number. Even if someday we support creating multiple * accounts within a smart contract call, we will still only need to track one created account diff --git a/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenUpdateRecordBuilder.java b/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenUpdateRecordBuilder.java index 7492c3e2b513..441ea3e709b7 100644 --- a/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenUpdateRecordBuilder.java +++ b/hedera-node/hedera-token-service/src/main/java/com/hedera/node/app/service/token/records/TokenUpdateRecordBuilder.java @@ -23,7 +23,7 @@ * A {@code RecordBuilder} specialization for tracking the effects of a {@code TokenUpdate} * transaction. */ -public interface TokenUpdateRecordBuilder { +public interface TokenUpdateRecordBuilder extends TokenBaseRecordBuilder { /** * Adds the token relations that are created by auto associations. * This information is needed while building the transfer list, to set the auto association flag.