-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add EntityIdSingleton for modularized (#10503)
This PR add an EntityIdSingleton implementation for getting a peek of the latest entity id. This is needed because currently without custom implementation and db reads if we make a contract call that internally has a contract create - the contract will be assigned the first id after the last system account clashing with already existing accounts. EntityIdSingleton - implements get method - to retrieve the first available entityId from db EntityRepository - adds query to retrieve the first available entityId after the last system account --------- Signed-off-by: Kristiyan Selveliev <[email protected]>
- Loading branch information
1 parent
5be0df2
commit 6335082
Showing
10 changed files
with
252 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
...a-mirror-web3/src/main/java/com/hedera/mirror/web3/state/singleton/EntityIdSingleton.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package com.hedera.mirror.web3.state.singleton; | ||
|
||
import static com.hedera.node.app.ids.schemas.V0490EntityIdSchema.ENTITY_ID_STATE_KEY; | ||
|
||
import com.hedera.hapi.node.state.common.EntityNumber; | ||
import com.hedera.mirror.common.CommonProperties; | ||
import com.hedera.mirror.common.domain.entity.EntityId; | ||
import com.hedera.mirror.web3.evm.properties.MirrorNodeEvmProperties; | ||
import com.hedera.mirror.web3.repository.EntityRepository; | ||
import com.hedera.node.config.data.HederaConfig; | ||
import jakarta.inject.Named; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Named | ||
@RequiredArgsConstructor | ||
@SuppressWarnings("deprecation") | ||
public class EntityIdSingleton implements SingletonState<EntityNumber> { | ||
private final EntityRepository entityRepository; | ||
private final MirrorNodeEvmProperties mirrorNodeEvmProperties; | ||
private final CommonProperties commonProperties; | ||
|
||
@Override | ||
public String getKey() { | ||
return ENTITY_ID_STATE_KEY; | ||
} | ||
|
||
@Override | ||
public EntityNumber get() { | ||
final long firstUserEntity = mirrorNodeEvmProperties | ||
.getVersionedConfiguration() | ||
.getConfigData(HederaConfig.class) | ||
.firstUserEntity(); | ||
|
||
final Long maxId = entityRepository.findMaxId(commonProperties.getShard(), commonProperties.getRealm()); | ||
|
||
if (maxId == null) { | ||
return new EntityNumber(EntityId.of(firstUserEntity).getNum()); | ||
} | ||
|
||
final var maxEntityId = EntityId.of(maxId); | ||
final var nextId = Math.max(maxEntityId.getNum() + 1, firstUserEntity); | ||
return new EntityNumber(nextId); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
...rc/test/java/com/hedera/mirror/web3/state/singleton/EntityIdSingletonIntegrationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package com.hedera.mirror.web3.state.singleton; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import com.hedera.mirror.common.CommonProperties; | ||
import com.hedera.mirror.web3.Web3IntegrationTest; | ||
import lombok.RequiredArgsConstructor; | ||
import org.junit.jupiter.api.Test; | ||
|
||
@RequiredArgsConstructor | ||
class EntityIdSingletonIntegrationTest extends Web3IntegrationTest { | ||
|
||
private final EntityIdSingleton entityIdSingleton; | ||
private final CommonProperties commonProperties; | ||
|
||
@Test | ||
void shouldReturnNextIdWithIncrementAndRealmAndShard() { | ||
// Create an entity with shard and realm set to (1,1) | ||
final var entityWithShardAndRealm = | ||
domainBuilder.entity().customize(e -> e.shard(1L).realm(1L)).persist(); | ||
|
||
// Get ID before setting the correct shard and realm | ||
final var entityNumberBeforeConfig = entityIdSingleton.get(); | ||
|
||
// Set correct shard and realm | ||
commonProperties.setRealm(1L); | ||
commonProperties.setShard(1L); | ||
final var entityNumberAfterConfig = entityIdSingleton.get(); | ||
|
||
// Reset to default shard and realm (0,0) | ||
commonProperties.setRealm(0L); | ||
commonProperties.setShard(0L); | ||
|
||
final var entity2 = domainBuilder.entity().persist(); | ||
final var entityNumber2 = entityIdSingleton.get(); | ||
|
||
final var entity3 = domainBuilder.entity().persist(); | ||
final var entityNumber3 = entityIdSingleton.get(); | ||
|
||
assertThat(entityNumberBeforeConfig.number()).isNotEqualTo(entityWithShardAndRealm.getNum() + 1); | ||
|
||
assertThat(entityNumberAfterConfig.number()).isEqualTo(entityWithShardAndRealm.getNum() + 1); | ||
|
||
assertThat(entityNumber2.number()).isEqualTo(entity2.getNum() + 1); | ||
|
||
assertThat(entityNumber3.number()).isEqualTo(entity3.getNum() + 1); | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
...rror-web3/src/test/java/com/hedera/mirror/web3/state/singleton/EntityIdSingletonTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package com.hedera.mirror.web3.state.singleton; | ||
|
||
import static com.hedera.mirror.web3.utils.ContractCallTestUtil.FIRST_USER_ENTITY_ID; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.mockito.Mockito.when; | ||
|
||
import com.hedera.mirror.common.CommonProperties; | ||
import com.hedera.mirror.web3.evm.properties.MirrorNodeEvmProperties; | ||
import com.hedera.mirror.web3.repository.EntityRepository; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.ExtendWith; | ||
import org.mockito.Mock; | ||
import org.mockito.junit.jupiter.MockitoExtension; | ||
|
||
@ExtendWith({MockitoExtension.class}) | ||
class EntityIdSingletonTest { | ||
|
||
private EntityIdSingleton entityIdSingleton; | ||
|
||
private CommonProperties commonProperties; | ||
|
||
@Mock | ||
private EntityRepository entityRepository; | ||
|
||
@BeforeEach | ||
void setup() { | ||
commonProperties = new CommonProperties(); | ||
entityIdSingleton = new EntityIdSingleton(entityRepository, new MirrorNodeEvmProperties(), commonProperties); | ||
} | ||
|
||
@Test | ||
void shouldReturnFirstUserEntityIdWhenMaxIdIsLessThanLastSystemAccount() { | ||
when(entityRepository.findMaxId(0, 0)).thenReturn(900L); | ||
assertThat(entityIdSingleton.get().number()).isEqualTo(FIRST_USER_ENTITY_ID); | ||
} | ||
|
||
@Test | ||
void shouldReturnFirstUserEntityIdWhenMaxIdIsNull() { | ||
when(entityRepository.findMaxId(0, 0)).thenReturn(null); | ||
assertThat(entityIdSingleton.get().number()).isEqualTo(FIRST_USER_ENTITY_ID); | ||
} | ||
|
||
@Test | ||
void shouldReturnNextIdWhenMaxIdIsGreaterThanLastSystemAccount() { | ||
long maxId = 2000; | ||
when(entityRepository.findMaxId(0, 0)).thenReturn(maxId); | ||
assertThat(entityIdSingleton.get().number()).isEqualTo(maxId + 1); | ||
} | ||
|
||
@Test | ||
void shouldReturnNextIdWhenMaxIdIsGreaterThanLastSystemAccountNonZeroRealmShard() { | ||
long maxId = 2000; | ||
commonProperties.setShard(1); | ||
commonProperties.setRealm(1); | ||
when(entityRepository.findMaxId(1, 1)).thenReturn(maxId); | ||
assertThat(entityIdSingleton.get().number()).isEqualTo(maxId + 1); | ||
} | ||
|
||
@Test | ||
void shouldIncrementIdMultipleTimes() { | ||
long currentMaxId = 1001L; | ||
long end = 1005L; | ||
for (long expectedId = currentMaxId + 1; expectedId <= end; expectedId++) { | ||
when(entityRepository.findMaxId(0, 0)).thenReturn(currentMaxId); | ||
assertThat(entityIdSingleton.get().number()).isEqualTo(expectedId); | ||
currentMaxId++; | ||
} | ||
} | ||
|
||
@Test | ||
void shouldReturnNextIdWhenMaxIdIsGreaterThanLastSystemAccountWithIncrement() { | ||
long maxId = 2000; | ||
when(entityRepository.findMaxId(0, 0)).thenReturn(maxId); | ||
assertThat(entityIdSingleton.get().number()).isEqualTo(maxId + 1); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters