Skip to content

Commit

Permalink
Fix unboxing issue causing errors in acceptance tests (#10375)
Browse files Browse the repository at this point in the history
After running acceptance tests against modularized web3 most of the web3 calls were failing. 
This was caused by a subtle bug caused by unboxing of null Long in `toAccountId` method called by `AccountReadableKVState`. `EntityId.of(id)` fails with nullPointer when id is null. 
Now just returning null if the id is null.
Reproduced with` Then I call estimateGas with associate function for fungible token` acceptance test.

* `ContractCallServicePrecompileModificationTest` - adds test to verify calls are passing null auto renew account now.
* `EntityIdUtils` - `toAccountId(final Long)` adds null check

---------

Signed-off-by: Kristiyan Selveliev <[email protected]>
  • Loading branch information
kselveliev authored Feb 13, 2025
1 parent 9f89e38 commit 2cf94b9
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ public static EntityId toEntityId(final com.hedera.hapi.node.base.FileID fileID)
}

public static com.hedera.hapi.node.base.AccountID toAccountId(final Long id) {
if (id == null) {
return null;
}
final var decodedEntityId = EntityId.of(id);

return toAccountId(decodedEntityId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,21 +203,44 @@ void associateToken(final Boolean single) throws Exception {
// Given
final var notAssociatedAccount = accountEntityPersist();

final var tokenEntity = tokenEntityPersist();
final var token = fungibleTokenPersist();
final var contract = testWeb3jService.deploy(ModificationPrecompileTestContract::deploy);

domainBuilder
.token()
.customize(t -> t.tokenId(tokenEntity.getId()).type(TokenTypeEnum.FUNGIBLE_COMMON))
.persist();
// When
final var functionCall = single
? contract.call_associateTokenExternal(
getAddressFromEntity(notAssociatedAccount),
toAddress(token.getTokenId()).toHexString())
: contract.call_associateTokensExternal(
getAddressFromEntity(notAssociatedAccount),
List.of(toAddress(token.getTokenId()).toHexString()));

// Then
verifyEthCallAndEstimateGas(functionCall, contract, ZERO_VALUE);
verifyOpcodeTracerCall(functionCall.encodeFunctionCall(), contract);
}

@ParameterizedTest
@ValueSource(booleans = {true, false})
void associateTokenWithNullAutoRenew(final Boolean single) throws Exception {
// Given
final var notAssociatedAccount = accountEntityPersistCustomizable(e -> e.type(EntityType.ACCOUNT)
.balance(DEFAULT_ACCOUNT_BALANCE)
.autoRenewAccountId(null)
.alias(null)
.evmAddress(null));

final var token = fungibleTokenPersist();
final var contract = testWeb3jService.deploy(ModificationPrecompileTestContract::deploy);

// When
final var functionCall = single
? contract.call_associateTokenExternal(
getAddressFromEntity(notAssociatedAccount), getAddressFromEntity(tokenEntity))
getAddressFromEntity(notAssociatedAccount),
toAddress(token.getTokenId()).toHexString())
: contract.call_associateTokensExternal(
getAddressFromEntity(notAssociatedAccount), List.of(getAddressFromEntity(tokenEntity)));
getAddressFromEntity(notAssociatedAccount),
List.of(toAddress(token.getTokenId()).toHexString()));

// Then
verifyEthCallAndEstimateGas(functionCall, contract, ZERO_VALUE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,11 @@ void toAccountIdFromId() {
assertEquals(expectedAccountId, EntityIdUtils.toAccountId(id));
}

@Test
void toAccountIdFromNullId() {
assertThat(EntityIdUtils.toAccountId((Long) null)).isNull();
}

@Test
void toAccountIdFromShardRealmNum() {
final var expectedAccountId = com.hedera.hapi.node.base.AccountID.newBuilder()
Expand Down

0 comments on commit 2cf94b9

Please sign in to comment.