From 32cf96bcec23ff49b167a53f142f70d501057f86 Mon Sep 17 00:00:00 2001 From: lukelee-sl Date: Wed, 7 Sep 2022 16:48:20 -0700 Subject: [PATCH 1/3] update token create and token update precompile selectors to match documentation/protobuf Signed-off-by: lukelee-sl --- .../contracts/precompile/AbiConstants.java | 20 ++ .../precompile/HTSPrecompiledContract.java | 12 +- .../precompile/codec/DecodingFacade.java | 259 +++++++++++++++++- .../impl/TokenCreatePrecompile.java | 8 + .../impl/TokenUpdatePrecompile.java | 16 +- .../precompile/CreatePrecompileTest.java | 114 ++++++++ .../HTSPrecompiledContractTest.java | 95 ++++--- .../precompile/TokenUpdatePrecompileTest.java | 61 +++++ .../precompile/codec/DecodingFacadeTest.java | 173 ++++++++++++ 9 files changed, 707 insertions(+), 51 deletions(-) diff --git a/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/AbiConstants.java b/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/AbiConstants.java index 4ff7ad1a8c20..c069ad6f86e4 100644 --- a/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/AbiConstants.java +++ b/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/AbiConstants.java @@ -113,6 +113,8 @@ private AbiConstants() { // updateTokenInfo(address token, HederaToken tokenInfo) public static final int ABI_ID_UPDATE_TOKEN_INFO = 0x2cccc36f; // updateTokenKeys(address token, TokenKey []) + public static final int ABI_ID_UPDATE_TOKEN_INFO_V2 = 0x18370d34; + // updateTokenKeys(address token, TokenKey []) public static final int ABI_ID_UPDATE_TOKEN_KEYS = 0x6fc3cbaf; // getTokenKey(address token, uint tokenType) public static final int ABI_ID_GET_TOKEN_KEY = 0x3c4dd32e; @@ -131,6 +133,8 @@ private AbiConstants() { // **** HIP-358 function selectors **** // createFungibleToken(HederaToken memory token, uint initialTotalSupply, uint decimals) public static final int ABI_ID_CREATE_FUNGIBLE_TOKEN = 0x7812a04b; + // createFungibleToken(HederaToken memory token, uint64 initialTotalSupply, uint32 decimals) + public static final int ABI_ID_CREATE_FUNGIBLE_TOKEN_V2 = 0xc23baeb6; // createFungibleTokenWithCustomFees( // HederaToken memory token, // uint initialTotalSupply, @@ -138,13 +142,29 @@ private AbiConstants() { // FixedFee[] memory fixedFees, // FractionalFee[] memory fractionalFees) public static final int ABI_ID_CREATE_FUNGIBLE_TOKEN_WITH_FEES = 0x4c381ae7; + // createFungibleTokenWithCustomFees( + // HederaToken memory token, + // uint64 initialTotalSupply, + // uint32 decimals, + // FixedFee[] memory fixedFees, + // FractionalFee[] memory fractionalFees) + public static final int ABI_ID_CREATE_FUNGIBLE_TOKEN_WITH_FEES_V2 = 0xb937581a; // createNonFungibleToken(HederaToken memory token) public static final int ABI_ID_CREATE_NON_FUNGIBLE_TOKEN = 0x9dc711e0; + // createNonFungibleToken(HederaToken memory token) + // HederaToken field maxSupply updated to int64 + public static final int ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_V2 = 0x9c89bb35; // createNonFungibleTokenWithCustomFees( // HederaToken memory token, // FixedFee[] memory fixedFees, // RoyaltyFee[] memory royaltyFees) public static final int ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES = 0x5bc7c0e6; + // createNonFungibleTokenWithCustomFees( + // HederaToken memory token, + // FixedFee[] memory fixedFees, + // RoyaltyFee[] memory royaltyFees) + // HederaToken field maxSupply updated to int64 + public static final int ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES_V2 = 0x45733969; // **** HIP-514 function selectors **** // getFungibleTokenInfo(address token) diff --git a/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/HTSPrecompiledContract.java b/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/HTSPrecompiledContract.java index b3af9eb8be50..53a7932ebc5b 100644 --- a/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/HTSPrecompiledContract.java +++ b/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/HTSPrecompiledContract.java @@ -519,7 +519,8 @@ void prepareComputation(final Bytes input, final UnaryOperator aliasReso syntheticTxnFactory, infrastructureFactory, precompilePricingUtils); - case AbiConstants.ABI_ID_UPDATE_TOKEN_INFO -> new TokenUpdatePrecompile( + case AbiConstants.ABI_ID_UPDATE_TOKEN_INFO, + AbiConstants.ABI_ID_UPDATE_TOKEN_INFO_V2 -> new TokenUpdatePrecompile( ledgers, updater.aliases(), decoder, @@ -527,7 +528,8 @@ void prepareComputation(final Bytes input, final UnaryOperator aliasReso sideEffectsTracker, syntheticTxnFactory, infrastructureFactory, - precompilePricingUtils); + precompilePricingUtils, + functionId); case AbiConstants.ABI_ID_UPDATE_TOKEN_KEYS -> new TokenUpdateKeysPrecompile( ledgers, updater.aliases(), @@ -711,8 +713,12 @@ yield switch (nestedFunctionSelector) { case AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN, AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN_WITH_FEES, AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN, + AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES, + AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN_V2, + AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN_WITH_FEES_V2, + AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_V2, AbiConstants - .ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES -> (dynamicProperties + .ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES_V2 -> (dynamicProperties .isHTSPrecompileCreateEnabled()) ? new TokenCreatePrecompile( ledgers, diff --git a/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/codec/DecodingFacade.java b/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/codec/DecodingFacade.java index 9e0d50aca13a..40c288c3c2ff 100644 --- a/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/codec/DecodingFacade.java +++ b/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/codec/DecodingFacade.java @@ -278,6 +278,13 @@ public class DecodingFacade { + "," + EXPIRY + ")"; + private static final String HEDERA_TOKEN_STRUCT_V2 = + "(string,string,address,string,bool,int64,bool," + + TOKEN_KEY + + ARRAY_BRACKETS + + "," + + EXPIRY + + ")"; private static final String HEDERA_TOKEN_STRUCT_DECODER = "(string,string,bytes32,string,bool,int64,bool," + TOKEN_KEY_DECODER @@ -290,6 +297,10 @@ public class DecodingFacade { new Function("createFungibleToken(" + HEDERA_TOKEN_STRUCT + ",uint256,uint256)"); private static final Bytes TOKEN_CREATE_FUNGIBLE_SELECTOR = Bytes.wrap(TOKEN_CREATE_FUNGIBLE_FUNCTION.selector()); + private static final Function TOKEN_CREATE_FUNGIBLE_FUNCTION_V2 = + new Function("createFungibleToken(" + HEDERA_TOKEN_STRUCT_V2 + ",uint64,uint32)"); + private static final Bytes TOKEN_CREATE_FUNGIBLE_SELECTOR_V2 = + Bytes.wrap(TOKEN_CREATE_FUNGIBLE_FUNCTION_V2.selector()); private static final ABIType TOKEN_CREATE_FUNGIBLE_DECODER = TypeFactory.create("(" + HEDERA_TOKEN_STRUCT_DECODER + ",uint256,uint256)"); @@ -297,9 +308,12 @@ public class DecodingFacade { new Function("createNonFungibleToken(" + HEDERA_TOKEN_STRUCT + ")"); private static final Bytes TOKEN_CREATE_NON_FUNGIBLE_SELECTOR = Bytes.wrap(TOKEN_CREATE_NON_FUNGIBLE_FUNCTION.selector()); + private static final Function TOKEN_CREATE_NON_FUNGIBLE_FUNCTION_V2 = + new Function("createNonFungibleToken(" + HEDERA_TOKEN_STRUCT_V2 + ")"); + private static final Bytes TOKEN_CREATE_NON_FUNGIBLE_SELECTOR_V2 = + Bytes.wrap(TOKEN_CREATE_NON_FUNGIBLE_FUNCTION_V2.selector()); private static final ABIType TOKEN_CREATE_NON_FUNGIBLE_DECODER = TypeFactory.create("(" + HEDERA_TOKEN_STRUCT_DECODER + ")"); - private static final Function TOKEN_CREATE_FUNGIBLE_WITH_FEES_FUNCTION = new Function( "createFungibleTokenWithCustomFees(" @@ -313,6 +327,19 @@ public class DecodingFacade { + ")"); private static final Bytes TOKEN_CREATE_FUNGIBLE_WITH_FEES_SELECTOR = Bytes.wrap(TOKEN_CREATE_FUNGIBLE_WITH_FEES_FUNCTION.selector()); + private static final Function TOKEN_CREATE_FUNGIBLE_WITH_FEES_FUNCTION_V2 = + new Function( + "createFungibleTokenWithCustomFees(" + + HEDERA_TOKEN_STRUCT_V2 + + ",uint64,uint32," + + FIXED_FEE + + ARRAY_BRACKETS + + "," + + FRACTIONAL_FEE + + ARRAY_BRACKETS + + ")"); + private static final Bytes TOKEN_CREATE_FUNGIBLE_WITH_FEES_SELECTOR_V2 = + Bytes.wrap(TOKEN_CREATE_FUNGIBLE_WITH_FEES_FUNCTION_V2.selector()); private static final ABIType TOKEN_CREATE_FUNGIBLE_WITH_FEES_DECODER = TypeFactory.create( "(" @@ -338,6 +365,20 @@ public class DecodingFacade { + ")"); private static final Bytes TOKEN_CREATE_NON_FUNGIBLE_WITH_FEES_SELECTOR = Bytes.wrap(TOKEN_CREATE_NON_FUNGIBLE_WITH_FEES_FUNCTION.selector()); + + private static final Function TOKEN_CREATE_NON_FUNGIBLE_WITH_FEES_FUNCTION_V2 = + new Function( + "createNonFungibleTokenWithCustomFees(" + + HEDERA_TOKEN_STRUCT_V2 + + "," + + FIXED_FEE + + ARRAY_BRACKETS + + "," + + ROYALTY_FEE + + ARRAY_BRACKETS + + ")"); + private static final Bytes TOKEN_CREATE_NON_FUNGIBLE_WITH_FEES_SELECTOR_V2 = + Bytes.wrap(TOKEN_CREATE_NON_FUNGIBLE_WITH_FEES_FUNCTION_V2.selector()); private static final ABIType TOKEN_CREATE_NON_FUNGIBLE_WITH_FEES_DECODER = TypeFactory.create( "(" @@ -468,6 +509,10 @@ public class DecodingFacade { new Function("updateTokenInfo(address," + HEDERA_TOKEN_STRUCT + ")"); private static final Bytes TOKEN_UPDATE_INFO_SELECTOR = Bytes.wrap(TOKEN_UPDATE_INFO_FUNCTION.selector()); + private static final Function TOKEN_UPDATE_INFO_FUNCTION_V2 = + new Function("updateTokenInfo(address," + HEDERA_TOKEN_STRUCT_V2 + ")"); + private static final Bytes TOKEN_UPDATE_INFO_SELECTOR_V2 = + Bytes.wrap(TOKEN_UPDATE_INFO_FUNCTION_V2.selector()); private static final ABIType TOKEN_UPDATE_INFO_DECODER = TypeFactory.create( "(" + removeBrackets(BYTES32) + "," + HEDERA_TOKEN_STRUCT_DECODER + ")"); @@ -969,6 +1014,18 @@ public Dissociation decodeMultipleDissociations( return Dissociation.multiDissociation(accountID, tokenIDs); } + /** + * Decodes the given bytes of the fungible token. + * + *

Important: This is an old version of this method and is superseded by + * decodeFungibleCreateV2(). The selector for this function is derived from: + * createFungibleToken((string,string,address,string,bool,uint32,bool,(uint256,(bool,address,bytes,bytes,address))[], + * (uint32,address,uint32)),uint256,uint256) + * + * @param input encoded bytes containing selector and input parameters + * @param aliasResolver function used to resolve aliases + * @return TokenCreateWrapper codec + */ public TokenCreateWrapper decodeFungibleCreate( final Bytes input, final UnaryOperator aliasResolver) { final Tuple decodedArguments = @@ -983,6 +1040,19 @@ public TokenCreateWrapper decodeFungibleCreate( aliasResolver); } + /** + * Decodes the given bytes of the fungible token. + * + *

Important: This is an old version of this method and is superseded by + * decodeFungibleCreateWithFeesV2(). The selector for this function is derived from: + * createFungibleTokenWithCustomFees((string,string,address,string,bool,uint32,bool,(uint256,(bool,address,bytes, + * bytes,address))[],(uint32,address,uint32)),uint256,uint256,(uint32,address,bool,bool,address)[], + * (uint32,uint32,uint32,uint32,bool,address)[]) + * + * @param input encoded bytes containing selector and input parameters + * @param aliasResolver function used to resolve aliases + * @return TokenCreateWrapper codec + */ public TokenCreateWrapper decodeFungibleCreateWithFees( final Bytes input, final UnaryOperator aliasResolver) { final Tuple decodedArguments = @@ -1006,6 +1076,18 @@ public TokenCreateWrapper decodeFungibleCreateWithFees( return tokenCreateWrapper; } + /** + * Decodes the given bytes of the non-fungible token. + * + *

Important: This is an old version of this method and is superseded by + * decodeNonFungibleCreateV2(). The selector for this function is derived from: + * createNonFungibleToken((string,string,address,string,bool,uint32,bool,(uint256,(bool,address,bytes,bytes,address))[], + * (uint32,address,uint32))) + * + * @param input encoded bytes containing selector and input parameters + * @param aliasResolver function used to resolve aliases + * @return TokenCreateWrapper codec + */ public TokenCreateWrapper decodeNonFungibleCreate( final Bytes input, final UnaryOperator aliasResolver) { final Tuple decodedArguments = @@ -1018,6 +1100,19 @@ public TokenCreateWrapper decodeNonFungibleCreate( decodedArguments.get(0), false, BigInteger.ZERO, BigInteger.ZERO, aliasResolver); } + /** + * Decodes the given bytes of the non-fungible token. + * + *

Important: This is an old version of this method and is superseded by + * decodeNonFungibleCreateV2(). The selector for this function is derived from: + * createNonFungibleTokenWithCustomFees((string,string,address,string,bool,uint32,bool,(uint256,(bool,address, + * bytes,bytes,address))[],(uint32,address,uint32)),(uint32,address,bool,bool,address)[], + * (uint32,uint32,uint32,address,bool,address)[]) + * + * @param input encoded bytes containing selector and input parameters + * @param aliasResolver function used to resolve aliases + * @return TokenCreateWrapper codec + */ public TokenCreateWrapper decodeNonFungibleCreateWithFees( final Bytes input, final UnaryOperator aliasResolver) { final Tuple decodedArguments = @@ -1041,6 +1136,128 @@ public TokenCreateWrapper decodeNonFungibleCreateWithFees( return tokenCreateWrapper; } + /** + * Decodes the given bytes of the fungible token. + * + *

Important: This is the latest version and supersedes decodeFungibleCreate(). The + * selector for this function is derived from: + * createFungibleToken((string,string,address,string,bool,int64,bool,(uint256,(bool,address,bytes,bytes,address))[], + * (uint32,address,uint32)),uint64,uint32) + * + * @param input encoded bytes containing selector and input parameters + * @param aliasResolver function used to resolve aliases + * @return TokenCreateWrapper codec + */ + public TokenCreateWrapper decodeFungibleCreateV2( + final Bytes input, final UnaryOperator aliasResolver) { + final Tuple decodedArguments = + decodeFunctionCall( + input, TOKEN_CREATE_FUNGIBLE_SELECTOR_V2, TOKEN_CREATE_FUNGIBLE_DECODER); + + return decodeTokenCreateWithoutFees( + decodedArguments.get(0), + true, + decodedArguments.get(1), + decodedArguments.get(2), + aliasResolver); + } + + /** + * Decodes the given bytes of the fungible token. + * + *

Important: This is the latest version and supersedes + * decodeFungibleCreateWithFees(). The selector for this function is derived from: + * createFungibleTokenWithCustomFees((string,string,address,string,bool,int64,bool,(uint256,(bool,address,bytes, + * bytes,address))[],(uint32,address,uint32)),uint64,uint32,(uint32,address,bool,bool,address)[], + * (uint32,uint32,uint32,uint32,bool,address)[]) + * + * @param input encoded bytes containing selector and input parameters + * @param aliasResolver function used to resolve aliases + * @return TokenCreateWrapper codec + */ + public TokenCreateWrapper decodeFungibleCreateWithFeesV2( + final Bytes input, final UnaryOperator aliasResolver) { + final Tuple decodedArguments = + decodeFunctionCall( + input, + TOKEN_CREATE_FUNGIBLE_WITH_FEES_SELECTOR_V2, + TOKEN_CREATE_FUNGIBLE_WITH_FEES_DECODER); + + final var tokenCreateWrapper = + decodeTokenCreateWithoutFees( + decodedArguments.get(0), + true, + decodedArguments.get(1), + decodedArguments.get(2), + aliasResolver); + final var fixedFees = decodeFixedFees(decodedArguments.get(3), aliasResolver); + final var fractionalFees = decodeFractionalFees(decodedArguments.get(4), aliasResolver); + tokenCreateWrapper.setFixedFees(fixedFees); + tokenCreateWrapper.setFractionalFees(fractionalFees); + + return tokenCreateWrapper; + } + + /** + * Decodes the given bytes of the non-fungible token. + * + *

Important: This is the latest version and supersedes decodeNonFungibleCreateV2(). + * The selector for this function is derived from: + * createNonFungibleToken((string,string,address,string,bool,int64,bool,(uint256,(bool,address,bytes,bytes,address))[], + * (uint32,address,uint32))) + * + * @param input encoded bytes containing selector and input parameters + * @param aliasResolver function used to resolve aliases + * @return TokenCreateWrapper codec + */ + public TokenCreateWrapper decodeNonFungibleCreateV2( + final Bytes input, final UnaryOperator aliasResolver) { + final Tuple decodedArguments = + decodeFunctionCall( + input, + TOKEN_CREATE_NON_FUNGIBLE_SELECTOR_V2, + TOKEN_CREATE_NON_FUNGIBLE_DECODER); + + return decodeTokenCreateWithoutFees( + decodedArguments.get(0), false, BigInteger.ZERO, BigInteger.ZERO, aliasResolver); + } + + /** + * Decodes the given bytes of the non-fungible token. + * + *

Important: This is the latest version and supersedes + * decodeNonFungibleCreateWithFees(). The selector for this function is derived from: + * createNonFungibleTokenWithCustomFees((string,string,address,string,bool,int64,bool,(uint256,(bool,address,bytes, + * bytes,address))[],(uint32,address,uint32)),(uint32,address,bool,bool,address)[], + * (uint32,uint32,uint32,address,bool,address)[]) + * + * @param input encoded bytes containing selector and input parameters + * @param aliasResolver function used to resolve aliases + * @return TokenCreateWrapper codec + */ + public TokenCreateWrapper decodeNonFungibleCreateWithFeesV2( + final Bytes input, final UnaryOperator aliasResolver) { + final Tuple decodedArguments = + decodeFunctionCall( + input, + TOKEN_CREATE_NON_FUNGIBLE_WITH_FEES_SELECTOR_V2, + TOKEN_CREATE_NON_FUNGIBLE_WITH_FEES_DECODER); + + final var tokenCreateWrapper = + decodeTokenCreateWithoutFees( + decodedArguments.get(0), + false, + BigInteger.ZERO, + BigInteger.ZERO, + aliasResolver); + final var fixedFees = decodeFixedFees(decodedArguments.get(1), aliasResolver); + final var royaltyFees = decodeRoyaltyFees(decodedArguments.get(2), aliasResolver); + tokenCreateWrapper.setFixedFees(fixedFees); + tokenCreateWrapper.setRoyaltyFees(royaltyFees); + + return tokenCreateWrapper; + } + public TokenInfoWrapper decodeGetTokenInfo(final Bytes input) { final Tuple decodedArguments = decodeFunctionCall(input, GET_TOKEN_INFO_SELECTOR, GET_TOKEN_INFO_DECODER); @@ -1425,6 +1642,17 @@ private static List decodeTokenIDsFromBytesArray( return accountIDs; } + /** + * Decodes the given bytes of the non-fungible token. + * + *

Important: This is an old version of this method and is superseded by + * decodeUpdateTokenInfoV2(). The selector for this function is derived from: + * updateTokenInfo(address,(string,string,address,string,bool,uint32,bool,(uint256,(bool,address,bytes,bytes,address))[],(uint32,address,uint32))) + * + * @param input encoded bytes containing selector and input parameters + * @param aliasResolver function used to resolve aliases + * @return TokenUpdateWrapper codec + */ public TokenUpdateWrapper decodeUpdateTokenInfo( Bytes input, UnaryOperator aliasResolver) { final Tuple decodedArguments = @@ -1443,6 +1671,35 @@ public TokenUpdateWrapper decodeUpdateTokenInfo( tokenID, tokenName, tokenSymbol, tokenTreasury, tokenMemo, tokenKeys, tokenExpiry); } + /** + * Decodes the given bytes of the updateTokenInfo function. + * + *

Important: This is the latest version and supersedes + * decodeNonFungibleCreateWithFees(). The selector for this function is derived from: + * updateTokenInfo(address,(string,string,address,string,bool,int64,bool,(uint256,(bool,address,bytes,bytes,address))[],(uint32,address,uint32))) + * + * @param input encoded bytes containing selector and input parameters + * @param aliasResolver function used to resolve aliases + * @return TokenUpdateWrapper codec + */ + public TokenUpdateWrapper decodeUpdateTokenInfoV2( + Bytes input, UnaryOperator aliasResolver) { + final Tuple decodedArguments = + decodeFunctionCall(input, TOKEN_UPDATE_INFO_SELECTOR_V2, TOKEN_UPDATE_INFO_DECODER); + final var tokenID = convertAddressBytesToTokenID(decodedArguments.get(0)); + + final Tuple hederaTokenStruct = decodedArguments.get(1); + final var tokenName = (String) hederaTokenStruct.get(0); + final var tokenSymbol = (String) hederaTokenStruct.get(1); + final var tokenTreasury = + convertLeftPaddedAddressToAccountId(hederaTokenStruct.get(2), aliasResolver); + final var tokenMemo = (String) hederaTokenStruct.get(3); + final var tokenKeys = decodeTokenKeys(hederaTokenStruct.get(7), aliasResolver); + final var tokenExpiry = decodeTokenExpiry(hederaTokenStruct.get(8), aliasResolver); + return new TokenUpdateWrapper( + tokenID, tokenName, tokenSymbol, tokenTreasury, tokenMemo, tokenKeys, tokenExpiry); + } + public TokenUpdateKeysWrapper decodeUpdateTokenKeys( Bytes input, UnaryOperator aliasResolver) { final Tuple decodedArguments = diff --git a/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/impl/TokenCreatePrecompile.java b/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/impl/TokenCreatePrecompile.java index efe452b03dcf..250080d62d4d 100644 --- a/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/impl/TokenCreatePrecompile.java +++ b/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/impl/TokenCreatePrecompile.java @@ -173,6 +173,14 @@ public TransactionBody.Builder body( .decodeNonFungibleCreate(input, aliasResolver); case AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES -> decoder .decodeNonFungibleCreateWithFees(input, aliasResolver); + case AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN_V2 -> decoder + .decodeFungibleCreateV2(input, aliasResolver); + case AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN_WITH_FEES_V2 -> decoder + .decodeFungibleCreateWithFeesV2(input, aliasResolver); + case AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_V2 -> decoder + .decodeNonFungibleCreateV2(input, aliasResolver); + case AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES_V2 -> decoder + .decodeNonFungibleCreateWithFeesV2(input, aliasResolver); default -> null; }; diff --git a/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/impl/TokenUpdatePrecompile.java b/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/impl/TokenUpdatePrecompile.java index 945465c4e2fa..c606edeccaa8 100644 --- a/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/impl/TokenUpdatePrecompile.java +++ b/hedera-node/src/main/java/com/hedera/services/store/contracts/precompile/impl/TokenUpdatePrecompile.java @@ -23,6 +23,7 @@ import com.hedera.services.contracts.sources.EvmSigsVerifier; import com.hedera.services.ledger.accounts.ContractAliases; import com.hedera.services.store.contracts.WorldLedgers; +import com.hedera.services.store.contracts.precompile.AbiConstants; import com.hedera.services.store.contracts.precompile.InfrastructureFactory; import com.hedera.services.store.contracts.precompile.SyntheticTxnFactory; import com.hedera.services.store.contracts.precompile.codec.DecodingFacade; @@ -37,6 +38,7 @@ public class TokenUpdatePrecompile extends AbstractTokenUpdatePrecompile { private TokenUpdateWrapper updateOp; + private final int functionId; public TokenUpdatePrecompile( WorldLedgers ledgers, @@ -46,7 +48,8 @@ public TokenUpdatePrecompile( SideEffectsTracker sideEffectsTracker, SyntheticTxnFactory syntheticTxnFactory, InfrastructureFactory infrastructureFactory, - PrecompilePricingUtils precompilePricingUtils) { + PrecompilePricingUtils precompilePricingUtils, + final int functionId) { super( ledgers, aliases, @@ -56,11 +59,20 @@ public TokenUpdatePrecompile( syntheticTxnFactory, infrastructureFactory, precompilePricingUtils); + + this.functionId = functionId; } @Override public TransactionBody.Builder body(Bytes input, UnaryOperator aliasResolver) { - updateOp = decoder.decodeUpdateTokenInfo(input, aliasResolver); + updateOp = + switch (functionId) { + case AbiConstants.ABI_ID_UPDATE_TOKEN_INFO -> decoder.decodeUpdateTokenInfo( + input, aliasResolver); + case AbiConstants.ABI_ID_UPDATE_TOKEN_INFO_V2 -> decoder + .decodeUpdateTokenInfoV2(input, aliasResolver); + default -> null; + }; transactionBody = syntheticTxnFactory.createTokenUpdate(updateOp); return transactionBody; } diff --git a/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/CreatePrecompileTest.java b/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/CreatePrecompileTest.java index 020357421b28..67dc82011a51 100644 --- a/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/CreatePrecompileTest.java +++ b/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/CreatePrecompileTest.java @@ -19,9 +19,13 @@ import static com.hedera.services.ledger.properties.AccountProperty.KEY; import static com.hedera.services.state.EntityCreator.EMPTY_MEMO; import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN_V2; import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN_WITH_FEES; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN_WITH_FEES_V2; import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_V2; import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES_V2; import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.account; import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.contractAddr; import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.contractAddress; @@ -399,6 +403,116 @@ void createNonFungibleWithFeesHappyPathWorks() { prepareAndAssertCreateHappyPathSucceeds(tokenCreateWrapper, pretendArguments); } + @Test + void createFungibleV2HappyPathWorks() { + // test-specific preparations + final var tokenCreateWrapper = + createTokenCreateWrapperWithKeys( + List.of( + new TokenKeyWrapper( + 1, + new KeyValueWrapper( + false, + EntityIdUtils.contractIdFromEvmAddress( + contractAddress), + new byte[] {}, + new byte[] {}, + null)), + new TokenKeyWrapper( + 8, + new KeyValueWrapper( + false, + null, + new byte[] {}, + new byte[] {}, + EntityIdUtils.contractIdFromEvmAddress( + contractAddress))))); + Bytes pretendArguments = Bytes.of(Integers.toBytes(ABI_ID_CREATE_FUNGIBLE_TOKEN_V2)); + given(decoder.decodeFungibleCreateV2(eq(pretendArguments), any())) + .willReturn(tokenCreateWrapper); + + prepareAndAssertCreateHappyPathSucceeds(tokenCreateWrapper, pretendArguments); + } + + @Test + void createFungibleWithFeesV2HappyPathWorks() { + // test-specific preparations + final var tokenCreateWrapper = + createTokenCreateWrapperWithKeys( + List.of( + new TokenKeyWrapper( + 1, + new KeyValueWrapper( + false, + null, + new byte[] {}, + new byte[] {}, + EntityIdUtils.contractIdFromEvmAddress( + contractAddress))))); + tokenCreateWrapper.setFixedFees(List.of(fixedFee)); + tokenCreateWrapper.setFractionalFees(List.of(HTSTestsUtil.fractionalFee)); + Bytes pretendArguments = + Bytes.of(Integers.toBytes(ABI_ID_CREATE_FUNGIBLE_TOKEN_WITH_FEES_V2)); + given(decoder.decodeFungibleCreateWithFeesV2(eq(pretendArguments), any())) + .willReturn(tokenCreateWrapper); + + prepareAndAssertCreateHappyPathSucceeds(tokenCreateWrapper, pretendArguments); + } + + @Test + void createNonFungibleV2HappyPathWorks() { + // test-specific preparations + final var tokenCreateWrapper = + createNonFungibleTokenCreateWrapperWithKeys( + List.of( + new TokenKeyWrapper( + 1, + new KeyValueWrapper( + false, + null, + new byte[] {}, + new byte + [JECDSASecp256k1Key + .ECDSA_SECP256K1_COMPRESSED_KEY_LENGTH], + null)))); + Bytes pretendArguments = Bytes.of(Integers.toBytes(ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_V2)); + given(decoder.decodeNonFungibleCreateV2(eq(pretendArguments), any())) + .willReturn(tokenCreateWrapper); + given(wrappedLedgers.accounts()).willReturn(accounts); + given(accounts.get(any(), eq(AUTO_RENEW_ACCOUNT_ID))) + .willReturn(EntityId.fromGrpcAccountId(account)); + given(sigsVerifier.cryptoKeyIsActive(any())).willReturn(true); + + prepareAndAssertCreateHappyPathSucceeds(tokenCreateWrapper, pretendArguments); + } + + @Test + void createNonFungibleV2WithFeesHappyPathWorks() { + // test-specific preparations + final var tokenCreateWrapper = + createNonFungibleTokenCreateWrapperWithKeys( + List.of( + new TokenKeyWrapper( + 1, + new KeyValueWrapper( + true, null, new byte[] {}, new byte[] {}, null)))); + tokenCreateWrapper.setFixedFees(List.of(fixedFee)); + tokenCreateWrapper.setRoyaltyFees(List.of(HTSTestsUtil.royaltyFee)); + Bytes pretendArguments = + Bytes.of(Integers.toBytes(ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES_V2)); + given(wrappedLedgers.accounts()).willReturn(accounts); + given(accounts.get(any(), eq(AUTO_RENEW_ACCOUNT_ID))) + .willReturn(EntityId.fromGrpcAccountId(account)); + given(decoder.decodeNonFungibleCreateWithFeesV2(eq(pretendArguments), any())) + .willReturn(tokenCreateWrapper); + given(accounts.get(any(), eq(KEY))) + .willReturn( + new JContractIDKey( + EntityIdUtils.contractIdFromEvmAddress(contractAddress))); + + prepareAndAssertCreateHappyPathSucceeds(tokenCreateWrapper, pretendArguments); + } + @Test void createFailurePath() { givenMinimalFrameContext(); diff --git a/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/HTSPrecompiledContractTest.java b/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/HTSPrecompiledContractTest.java index ee02f589a53f..3aa8cad4be08 100644 --- a/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/HTSPrecompiledContractTest.java +++ b/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/HTSPrecompiledContractTest.java @@ -16,51 +16,8 @@ package com.hedera.services.store.contracts.precompile; import static com.hedera.services.contracts.execution.HederaMessageCallProcessor.INVALID_TRANSFER; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_ASSOCIATE_TOKEN; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_ASSOCIATE_TOKENS; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_BURN_TOKEN; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN_WITH_FEES; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CRYPTO_TRANSFER; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_DISSOCIATE_TOKEN; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_DISSOCIATE_TOKENS; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_ERC_NAME; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_GET_TOKEN_CUSTOM_FEES; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_GET_TOKEN_EXPIRY_INFO; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_GET_TOKEN_INFO; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_MINT_TOKEN; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_PAUSE_TOKEN; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_REDIRECT_FOR_TOKEN; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_TRANSFER_NFT; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_TRANSFER_NFTS; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_TRANSFER_TOKEN; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_TRANSFER_TOKENS; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_UNPAUSE_TOKEN; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_UPDATE_TOKEN_EXPIRY_INFO; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_WIPE_TOKEN_ACCOUNT_FUNGIBLE; -import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_WIPE_TOKEN_ACCOUNT_NFT; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.TEST_CONSENSUS_TIME; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.associateOp; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.contractAddress; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.createTokenCreateWrapperWithKeys; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.customFeesWrapper; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.dissociateToken; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungible; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungibleBurn; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungibleMint; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungibleMintAmountOversize; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungiblePause; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungibleUnpause; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungibleWipe; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.getTokenExpiryInfoWrapper; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.multiDissociateOp; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.nonFungiblePause; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.nonFungibleUnpause; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.nonFungibleWipe; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.timestamp; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.tokenUpdateExpiryInfoWrapper; +import static com.hedera.services.store.contracts.precompile.AbiConstants.*; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.*; import static org.hyperledger.besu.evm.frame.MessageFrame.State.REVERT; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -595,6 +552,54 @@ void replacesInheritedPropertiesOnCreateNonFungibleToken() { verify(tokenCreateWrapper).inheritAutoRenewAccount(autoRenewId); } + @Test + void computeCallsCorrectImplementationForCreateFungibleTokenWithFeesV2() { + // given + Bytes input = Bytes.of(Integers.toBytes(ABI_ID_CREATE_FUNGIBLE_TOKEN_WITH_FEES_V2)); + given(decoder.decodeFungibleCreateWithFeesV2(any(), any())) + .willReturn(createTokenCreateWrapperWithKeys(Collections.emptyList())); + given(worldUpdater.permissivelyUnaliased(any())) + .willAnswer(invocationOnMock -> invocationOnMock.getArgument(0)); + + prepareAndAssertCorrectInstantiationOfTokenCreatePrecompile(input); + } + + @Test + void computeCallsCorrectImplementationForCreateNonFungibleTokenWithFeesV2() { + // given + Bytes input = Bytes.of(Integers.toBytes(ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES_V2)); + given(decoder.decodeNonFungibleCreateWithFeesV2(any(), any())) + .willReturn(createTokenCreateWrapperWithKeys(Collections.emptyList())); + given(worldUpdater.permissivelyUnaliased(any())) + .willAnswer(invocationOnMock -> invocationOnMock.getArgument(0)); + + prepareAndAssertCorrectInstantiationOfTokenCreatePrecompile(input); + } + + @Test + void computeCallsCorrectImplementationForCreateFungibleTokenV2() { + // given + Bytes input = Bytes.of(Integers.toBytes(ABI_ID_CREATE_FUNGIBLE_TOKEN_V2)); + given(decoder.decodeFungibleCreateV2(any(), any())) + .willReturn(createTokenCreateWrapperWithKeys(Collections.emptyList())); + given(worldUpdater.permissivelyUnaliased(any())) + .willAnswer(invocationOnMock -> invocationOnMock.getArgument(0)); + + prepareAndAssertCorrectInstantiationOfTokenCreatePrecompile(input); + } + + @Test + void computeCallsCorrectImplementationForCreateNonFungibleTokenV2() { + // given + Bytes input = Bytes.of(Integers.toBytes(ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_V2)); + given(decoder.decodeNonFungibleCreateV2(any(), any())) + .willReturn(createTokenCreateWrapperWithKeys(Collections.emptyList())); + given(worldUpdater.permissivelyUnaliased(any())) + .willAnswer(invocationOnMock -> invocationOnMock.getArgument(0)); + + prepareAndAssertCorrectInstantiationOfTokenCreatePrecompile(input); + } + @Test void computeCallsCorrectImplementationForCreateFungibleTokenWithFees() { // given diff --git a/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/TokenUpdatePrecompileTest.java b/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/TokenUpdatePrecompileTest.java index aba0574f4ce0..6e08e520bf3c 100644 --- a/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/TokenUpdatePrecompileTest.java +++ b/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/TokenUpdatePrecompileTest.java @@ -17,6 +17,7 @@ import static com.hedera.services.state.EntityCreator.EMPTY_MEMO; import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_UPDATE_TOKEN_INFO; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_UPDATE_TOKEN_INFO_V2; import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.contractAddr; import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.contractAddress; import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.createFungibleTokenUpdateWrapperWithKeys; @@ -177,6 +178,28 @@ void computeCallsSuccessfullyForUpdateFungibleToken() { assertEquals(successResult, result); } + @Test + void computeCallsSuccessfullyForUpdateFungibleTokenV2() { + // given + final var input = Bytes.of(Integers.toBytes(ABI_ID_UPDATE_TOKEN_INFO_V2)); + givenFrameContext(); + given(frame.getBlockValues()) + .willReturn(new HederaBlockValues(10L, 123L, Instant.ofEpochSecond(123L))); + givenLedgers(); + givenMinimalContextForSuccessfulCall(); + givenMinimalRecordStructureForSuccessfulCall(); + givenUpdateTokenContextV2(); + givenPricingUtilsContext(); + given(updateLogic.validate(any())).willReturn(OK); + // when + subject.prepareFields(frame); + subject.prepareComputation(input, a -> a); + subject.getPrecompile().getMinimumFeeInTinybars(Timestamp.getDefaultInstance()); + final var result = subject.computeInternal(frame); + // then + assertEquals(successResult, result); + } + @Test void failsWithWrongValidityForUpdateFungibleToken() { // given @@ -197,6 +220,26 @@ void failsWithWrongValidityForUpdateFungibleToken() { assertEquals(failResult, result); } + @Test + void failsWithWrongValidityForUpdateFungibleTokenV2() { + // given + final var input = Bytes.of(Integers.toBytes(ABI_ID_UPDATE_TOKEN_INFO)); + givenFrameContext(); + givenLedgers(); + givenMinimalContextForSuccessfulCall(); + givenUpdateTokenContextV2(); + given(worldUpdater.aliases()).willReturn(aliases); + given(worldUpdater.permissivelyUnaliased(any())) + .willAnswer(invocationOnMock -> invocationOnMock.getArgument(0)); + given(updateLogic.validate(any())).willReturn(FAIL_INVALID); + // when + subject.prepareFields(frame); + subject.prepareComputation(input, a -> a); + final var result = subject.computeInternal(frame); + // then + assertEquals(failResult, result); + } + private void givenFrameContext() { given(frame.getSenderAddress()).willReturn(contractAddress); given(frame.getWorldUpdater()).willReturn(worldUpdater); @@ -234,6 +277,24 @@ private void givenUpdateTokenContext() { .setTokenUpdate(TokenUpdateTransactionBody.newBuilder())); } + private void givenUpdateTokenContextV2() { + given( + sigsVerifier.hasActiveAdminKey( + true, fungibleTokenAddr, fungibleTokenAddr, wrappedLedgers)) + .willReturn(true); + given(infrastructureFactory.newHederaTokenStore(sideEffects, tokens, nfts, tokenRels)) + .willReturn(hederaTokenStore); + given( + infrastructureFactory.newTokenUpdateLogic( + hederaTokenStore, wrappedLedgers, sideEffects)) + .willReturn(updateLogic); + given(decoder.decodeUpdateTokenInfoV2(any(), any())).willReturn(updateWrapper); + given(syntheticTxnFactory.createTokenUpdate(updateWrapper)) + .willReturn( + TransactionBody.newBuilder() + .setTokenUpdate(TokenUpdateTransactionBody.newBuilder())); + } + private void givenMinimalRecordStructureForSuccessfulCall() { given( creator.createSuccessfulSyntheticRecord( diff --git a/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/codec/DecodingFacadeTest.java b/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/codec/DecodingFacadeTest.java index 2fdd1f2c2354..77a1f2581838 100644 --- a/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/codec/DecodingFacadeTest.java +++ b/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/codec/DecodingFacadeTest.java @@ -141,18 +141,34 @@ class DecodingFacadeTest { Bytes.fromHexString( "0x7812a04b000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000015b200000000000000000000000000000000000000000000000000000000000000074d79546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034d544b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046d656d6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); + private static final Bytes CREATE_FUNGIBLE_NO_FEES_INPUT_V2 = + Bytes.fromHexString( + "c23baeb600000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000007fffffffffffffff0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007fffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000000000000094d79546f6b656e5632000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054d544b563200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066d656d6f56320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); + private static final Bytes CREATE_FUNGIBLE_WITH_FEES_INPUT = Bytes.fromHexString( "0x4c381ae700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000015b200000000000000000000000000000000000000000000000000000000000000074d79546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034d544b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046d656d6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003"); + private static final Bytes CREATE_FUNGIBLE_WITH_FEES_INPUT_V2 = + Bytes.fromHexString( + "0xb937581a00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000007fffffffffffffff000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007fffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000000000000094d79546f6b656e5632000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054d544b563200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000066d656d6f56320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"); + private static final Bytes CREATE_NON_FUNGIBLE_NO_FEES_INPUT = Bytes.fromHexString( "0x9dc711e00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000004071b890000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054d794e465400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034e4654000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076e66744d656d6f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); + private static final Bytes CREATE_NON_FUNGIBLE_NO_FEES_INPUT_V2 = + Bytes.fromHexString( + "0x9c89bb350000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000007fffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000000000000074d794e465456320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054e4654563200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096e66744d656d6f56320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); + private static final Bytes CREATE_NON_FUNGIBLE_WITH_FEES_INPUT = Bytes.fromHexString( "0x5bc7c0e6000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000004071b890000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054d794e465400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034e4654000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076e66744d656d6f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003f100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000003f1000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); + private static final Bytes CREATE_NON_FUNGIBLE_WITH_FEES_INPUT_V2 = + Bytes.fromHexString( + "0x457339690000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000052000000000000000000000000000000000000000000000000000000000000005e0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000007fffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000000000000074d794e465456320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054e4654563200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096e66744d656d6f56320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002"); + private static final Bytes CREATE_FUNGIBLE_WITH_FEES_INPUT_NULL_ACCOUNTS = Bytes.fromHexString( "0x4c381ae700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000005600000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000015b200000000000000000000000000000000000000000000000000000000000000074d79546f6b656e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034d544b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046d656d6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000037000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000"); @@ -290,6 +306,10 @@ class DecodingFacadeTest { Bytes.fromHexString( "0x2cccc36f0000000000000000000000000000000000000000000000000000000000000b650000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000b6100000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6100000000000000000000000000000000000000000000000000000000007a1200000000000000000000000000000000000000000000000000000000000000000a637573746f6d4e616d65000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002cea900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054f6d656761000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000205d2a3c5dd3e65bde502cacc8bc88a12599712d3d7f6d96aa0db12e140740a65e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000210324e3e6c5a305f98e36ee89783d1aedcf07140780b5bb16d5d2aa7911ccdf8bdf000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6400000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6400000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000b6400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); + private static final Bytes UPDATE_FUNGIBLE_TOKEN_INPUT_V2 = + Bytes.fromHexString( + "0x18370d3400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000b6100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000007fffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6100000000000000000000000000000000000000000000000000000000007a1200000000000000000000000000000000000000000000000000000000000000000a637573746f6d4e616d65000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002cea900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000054f6d656761000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); + private static final Bytes UPDATE_FUNGIBLE_TOKEN_KEYS = Bytes.fromHexString( "0x6fc3cbaf00000000000000000000000000000000000000000000000000000000000010650000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000201aeca66efce3b1c581d865197a41880b6c05c3115cfeac97f2832c2198f49f570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021031929ec5ff0aeef191aff1a4f0775470da849d92fc5eaed6e22b4c829ca5e99b400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000106400000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000106400000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000106400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); @@ -912,6 +932,151 @@ void decodeNonFungibleCreateWithFeesInput() { assertNull(royaltyFeeWrapper2.feeCollector()); } + @Test + void decodeFungibleCreateNoFeesInputV2() { + final var decodedInput = + subject.decodeFungibleCreateV2(CREATE_FUNGIBLE_NO_FEES_INPUT_V2, identity()); + + assertEquals(BigInteger.valueOf(9223372036854775807L), decodedInput.getInitSupply()); + assertEquals(BigInteger.valueOf(4), decodedInput.getDecimals()); + assertExpectedKeys(decodedInput); + + assertTrue(decodedInput.isFungible()); + assertEquals("MyTokenV2", decodedInput.getName()); + assertEquals("MTKV2", decodedInput.getSymbol()); + assertEquals(AccountID.newBuilder().setAccountNum(1L).build(), decodedInput.getTreasury()); + assertEquals("memoV2", decodedInput.getMemo()); + assertFalse(decodedInput.isSupplyTypeFinite()); + assertEquals(9223372036854775807L, decodedInput.getMaxSupply()); + assertFalse(decodedInput.isFreezeDefault()); + assertEquals(8000000, decodedInput.getExpiry().autoRenewPeriod()); + assertEquals( + AccountID.newBuilder().setAccountNum(4L).build(), + decodedInput.getExpiry().autoRenewAccount()); + assertEquals(0L, decodedInput.getExpiry().second()); + } + + @Test + void decodeFungibleCreate4WithFeesInputV2() { + final var decodedInput = + subject.decodeFungibleCreateWithFeesV2( + CREATE_FUNGIBLE_WITH_FEES_INPUT_V2, identity()); + + assertTrue(decodedInput.isFungible()); + assertEquals("MyTokenV2", decodedInput.getName()); + assertEquals("MTKV2", decodedInput.getSymbol()); + assertEquals(AccountID.newBuilder().setAccountNum(1L).build(), decodedInput.getTreasury()); + assertEquals("memoV2", decodedInput.getMemo()); + assertFalse(decodedInput.isSupplyTypeFinite()); + assertEquals(9223372036854775807L, decodedInput.getMaxSupply()); + assertFalse(decodedInput.isFreezeDefault()); + assertEquals(8000000, decodedInput.getExpiry().autoRenewPeriod()); + assertEquals( + AccountID.newBuilder().setAccountNum(4L).build(), + decodedInput.getExpiry().autoRenewAccount()); + assertEquals(0L, decodedInput.getExpiry().second()); + + assertEquals(decodedInput.getInitSupply(), BigInteger.valueOf(9223372036854775807L)); + assertEquals(decodedInput.getDecimals(), BigInteger.valueOf(4)); + assertExpectedKeys(decodedInput); + + final var fixedFees = decodedInput.getFixedFees(); + assertEquals(1, fixedFees.size()); + final var fixedFeeWrapper = fixedFees.get(0); + assertEquals(USE_EXISTING_FUNGIBLE_TOKEN, fixedFeeWrapper.getFixedFeePayment()); + final var customFee = fixedFeeWrapper.asGrpc(); + assertEquals(0, customFee.getFixedFee().getAmount()); + assertEquals( + TokenID.newBuilder().setTokenNum(1).setRealmNum(0).setShardNum(0).build(), + customFee.getFixedFee().getDenominatingTokenId()); + assertEquals( + AccountID.newBuilder().setAccountNum(1).build(), + customFee.getFeeCollectorAccountId()); + + final var fractionalFees = decodedInput.getFractionalFees(); + assertEquals(1, fractionalFees.size()); + final var fractionalFeeWrapper = fractionalFees.get(0); + assertEquals(1, fractionalFeeWrapper.numerator()); + assertEquals(1, fractionalFeeWrapper.denominator()); + assertEquals(1, fractionalFeeWrapper.minimumAmount()); + assertEquals(1, fractionalFeeWrapper.maximumAmount()); + assertFalse(fractionalFeeWrapper.netOfTransfers()); + assertEquals( + AccountID.newBuilder().setAccountNum(1).build(), + fractionalFeeWrapper.feeCollector()); + } + + @Test + void decodeNonFungibleCreateNoFeesInputV2() { + final var decodedInput = + subject.decodeNonFungibleCreateV2(CREATE_NON_FUNGIBLE_NO_FEES_INPUT_V2, identity()); + + assertFalse(decodedInput.isFungible()); + assertEquals("MyNFTV2", decodedInput.getName()); + assertEquals("NFTV2", decodedInput.getSymbol()); + assertEquals(AccountID.newBuilder().setAccountNum(1L).build(), decodedInput.getTreasury()); + assertEquals("nftMemoV2", decodedInput.getMemo()); + assertTrue(decodedInput.isSupplyTypeFinite()); + assertEquals(9223372036854775807L, decodedInput.getMaxSupply()); + assertFalse(decodedInput.isFreezeDefault()); + assertEquals(0L, decodedInput.getExpiry().second()); + assertEquals(8000000L, decodedInput.getExpiry().autoRenewPeriod()); + assertEquals( + AccountID.newBuilder().setAccountNum(4L).build(), + decodedInput.getExpiry().autoRenewAccount()); + assertEquals(BigInteger.valueOf(0), decodedInput.getInitSupply()); + assertEquals(BigInteger.valueOf(0), decodedInput.getDecimals()); + assertExpectedKeys(decodedInput); + } + + @Test + void decodeNonFungibleCreateWithFeesInputV2() { + final var decodedInput = + subject.decodeNonFungibleCreateWithFeesV2( + CREATE_NON_FUNGIBLE_WITH_FEES_INPUT_V2, identity()); + + assertFalse(decodedInput.isFungible()); + assertEquals("MyNFTV2", decodedInput.getName()); + assertEquals("NFTV2", decodedInput.getSymbol()); + assertEquals(AccountID.newBuilder().setAccountNum(1L).build(), decodedInput.getTreasury()); + assertEquals("nftMemoV2", decodedInput.getMemo()); + assertTrue(decodedInput.isSupplyTypeFinite()); + assertEquals(9223372036854775807L, decodedInput.getMaxSupply()); + assertFalse(decodedInput.isFreezeDefault()); + assertEquals(0L, decodedInput.getExpiry().second()); + assertEquals(8000000L, decodedInput.getExpiry().autoRenewPeriod()); + assertEquals( + AccountID.newBuilder().setAccountNum(4L).build(), + decodedInput.getExpiry().autoRenewAccount()); + assertEquals(BigInteger.valueOf(0), decodedInput.getInitSupply()); + assertEquals(BigInteger.valueOf(0), decodedInput.getDecimals()); + assertExpectedKeys(decodedInput); + + final var fixedFees = decodedInput.getFixedFees(); + assertEquals(1, fixedFees.size()); + final var fixedFeeWrapper = fixedFees.get(0); + assertEquals(USE_EXISTING_FUNGIBLE_TOKEN, fixedFeeWrapper.getFixedFeePayment()); + final var customFee = fixedFeeWrapper.asGrpc(); + assertEquals(0, customFee.getFixedFee().getAmount()); + assertEquals( + TokenID.newBuilder().setTokenNum(1).build(), + customFee.getFixedFee().getDenominatingTokenId()); + assertEquals( + AccountID.newBuilder().setAccountNum(1).build(), + customFee.getFeeCollectorAccountId()); + + final var royaltyFees = decodedInput.getRoyaltyFees(); + assertEquals(1, royaltyFees.size()); + final var royaltyFeeWrapper = royaltyFees.get(0); + assertEquals(1, royaltyFeeWrapper.numerator()); + assertEquals(2, royaltyFeeWrapper.denominator()); + final var actualFallbackFee = royaltyFeeWrapper.fallbackFixedFee().asGrpc(); + assertEquals(3, actualFallbackFee.getFixedFee().getAmount()); + assertTrue(actualFallbackFee.getFixedFee().hasDenominatingTokenId()); + assertEquals( + AccountID.newBuilder().setAccountNum(2).build(), royaltyFeeWrapper.feeCollector()); + } + @Test void decodeTokenCreateWithEmptyAddressesAsExpected() { final var decodedInput = @@ -1082,6 +1247,14 @@ void decodeFungibleUpdateInput() { assertExpectedFungibleTokenUpdateStruct(decodedInput); } + @Test + void decodeFungibleUpdateInpuV2() { + final var decodedInput = + subject.decodeUpdateTokenInfoV2(UPDATE_FUNGIBLE_TOKEN_INPUT_V2, identity()); + + assertExpectedFungibleTokenUpdateStruct(decodedInput); + } + @Test void decodeGetExpiryInfoForTokenInput() { final var decodedInput = subject.decodeGetTokenExpiryInfo(GET_EXPIRY_INFO_FOR_TOKEN_INPUT); From 799cc700ae903f40504016d783c54abc3b0428d5 Mon Sep 17 00:00:00 2001 From: lukelee-sl Date: Wed, 7 Sep 2022 17:09:18 -0700 Subject: [PATCH 2/3] fix * static import Signed-off-by: lukelee-sl --- .../HTSPrecompiledContractTest.java | 51 ++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/HTSPrecompiledContractTest.java b/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/HTSPrecompiledContractTest.java index 3aa8cad4be08..ce0f5830442c 100644 --- a/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/HTSPrecompiledContractTest.java +++ b/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/HTSPrecompiledContractTest.java @@ -16,8 +16,55 @@ package com.hedera.services.store.contracts.precompile; import static com.hedera.services.contracts.execution.HederaMessageCallProcessor.INVALID_TRANSFER; -import static com.hedera.services.store.contracts.precompile.AbiConstants.*; -import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.*; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_ASSOCIATE_TOKEN; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_ASSOCIATE_TOKENS; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_BURN_TOKEN; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN_V2; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN_WITH_FEES; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_FUNGIBLE_TOKEN_WITH_FEES_V2; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_V2; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CREATE_NON_FUNGIBLE_TOKEN_WITH_FEES_V2; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_CRYPTO_TRANSFER; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_DISSOCIATE_TOKEN; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_DISSOCIATE_TOKENS; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_ERC_NAME; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_GET_TOKEN_CUSTOM_FEES; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_GET_TOKEN_EXPIRY_INFO; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_GET_TOKEN_INFO; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_MINT_TOKEN; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_PAUSE_TOKEN; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_REDIRECT_FOR_TOKEN; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_TRANSFER_NFT; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_TRANSFER_NFTS; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_TRANSFER_TOKEN; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_TRANSFER_TOKENS; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_UNPAUSE_TOKEN; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_ID_UPDATE_TOKEN_EXPIRY_INFO; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_WIPE_TOKEN_ACCOUNT_FUNGIBLE; +import static com.hedera.services.store.contracts.precompile.AbiConstants.ABI_WIPE_TOKEN_ACCOUNT_NFT; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.TEST_CONSENSUS_TIME; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.associateOp; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.contractAddress; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.createTokenCreateWrapperWithKeys; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.customFeesWrapper; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.dissociateToken; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungible; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungibleBurn; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungibleMint; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungibleMintAmountOversize; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungiblePause; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungibleUnpause; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.fungibleWipe; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.getTokenExpiryInfoWrapper; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.multiDissociateOp; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.nonFungiblePause; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.nonFungibleUnpause; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.nonFungibleWipe; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.timestamp; +import static com.hedera.services.store.contracts.precompile.HTSTestsUtil.tokenUpdateExpiryInfoWrapper; import static org.hyperledger.besu.evm.frame.MessageFrame.State.REVERT; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; From ea3098aad12e876d4e8fcb564898b11fa522b8e8 Mon Sep 17 00:00:00 2001 From: lukelee-sl Date: Wed, 7 Sep 2022 17:30:23 -0700 Subject: [PATCH 3/3] fix sonarcloud issue Signed-off-by: lukelee-sl --- .../precompile/codec/DecodingFacadeTest.java | 46 ++++++++----------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/codec/DecodingFacadeTest.java b/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/codec/DecodingFacadeTest.java index 77a1f2581838..7db0fdd3344f 100644 --- a/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/codec/DecodingFacadeTest.java +++ b/hedera-node/src/test/java/com/hedera/services/store/contracts/precompile/codec/DecodingFacadeTest.java @@ -941,40 +941,16 @@ void decodeFungibleCreateNoFeesInputV2() { assertEquals(BigInteger.valueOf(4), decodedInput.getDecimals()); assertExpectedKeys(decodedInput); - assertTrue(decodedInput.isFungible()); - assertEquals("MyTokenV2", decodedInput.getName()); - assertEquals("MTKV2", decodedInput.getSymbol()); - assertEquals(AccountID.newBuilder().setAccountNum(1L).build(), decodedInput.getTreasury()); - assertEquals("memoV2", decodedInput.getMemo()); - assertFalse(decodedInput.isSupplyTypeFinite()); - assertEquals(9223372036854775807L, decodedInput.getMaxSupply()); - assertFalse(decodedInput.isFreezeDefault()); - assertEquals(8000000, decodedInput.getExpiry().autoRenewPeriod()); - assertEquals( - AccountID.newBuilder().setAccountNum(4L).build(), - decodedInput.getExpiry().autoRenewAccount()); - assertEquals(0L, decodedInput.getExpiry().second()); + assertExpectedFungibleTokenCreateStructV2(decodedInput); } @Test - void decodeFungibleCreate4WithFeesInputV2() { + void decodeFungibleCreateWithFeesInputV2() { final var decodedInput = subject.decodeFungibleCreateWithFeesV2( CREATE_FUNGIBLE_WITH_FEES_INPUT_V2, identity()); - assertTrue(decodedInput.isFungible()); - assertEquals("MyTokenV2", decodedInput.getName()); - assertEquals("MTKV2", decodedInput.getSymbol()); - assertEquals(AccountID.newBuilder().setAccountNum(1L).build(), decodedInput.getTreasury()); - assertEquals("memoV2", decodedInput.getMemo()); - assertFalse(decodedInput.isSupplyTypeFinite()); - assertEquals(9223372036854775807L, decodedInput.getMaxSupply()); - assertFalse(decodedInput.isFreezeDefault()); - assertEquals(8000000, decodedInput.getExpiry().autoRenewPeriod()); - assertEquals( - AccountID.newBuilder().setAccountNum(4L).build(), - decodedInput.getExpiry().autoRenewAccount()); - assertEquals(0L, decodedInput.getExpiry().second()); + assertExpectedFungibleTokenCreateStructV2(decodedInput); assertEquals(decodedInput.getInitSupply(), BigInteger.valueOf(9223372036854775807L)); assertEquals(decodedInput.getDecimals(), BigInteger.valueOf(4)); @@ -1305,6 +1281,22 @@ private void assertExpectedFungibleTokenCreateStruct(final TokenCreateWrapper de assertEquals(0L, decodedInput.getExpiry().second()); } + private void assertExpectedFungibleTokenCreateStructV2(final TokenCreateWrapper decodedInput) { + assertTrue(decodedInput.isFungible()); + assertEquals("MyTokenV2", decodedInput.getName()); + assertEquals("MTKV2", decodedInput.getSymbol()); + assertEquals(AccountID.newBuilder().setAccountNum(1L).build(), decodedInput.getTreasury()); + assertEquals("memoV2", decodedInput.getMemo()); + assertFalse(decodedInput.isSupplyTypeFinite()); + assertEquals(9223372036854775807L, decodedInput.getMaxSupply()); + assertFalse(decodedInput.isFreezeDefault()); + assertEquals(8000000, decodedInput.getExpiry().autoRenewPeriod()); + assertEquals( + AccountID.newBuilder().setAccountNum(4L).build(), + decodedInput.getExpiry().autoRenewAccount()); + assertEquals(0L, decodedInput.getExpiry().second()); + } + private void assertExpectedNonFungibleTokenCreateStruct(final TokenCreateWrapper decodedInput) { assertFalse(decodedInput.isFungible()); assertEquals("MyNFT", decodedInput.getName());