Skip to content

feat: Virtual leaves should be hashed as valid block items #20401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,20 @@ import "services/state/tss/tss_message_map_key.proto";
import "services/state/tss/tss_vote_map_key.proto";

/**
* This message defines the Virtual Leaf.
* This message defines the State Item.
*/
message VirtualLeaf {
message StateItem {
/**
* Virtual Key.<br/>
* State Key.<br/>
* The key used to identify and locate this virtual map entry.
*/
VirtualMapKey key = 2;
StateKey key = 2;

/**
* Virtual Value.<br/>
* State Value.<br/>
* The actual data content stored for this virtual map entry.
*/
VirtualMapValue value = 3;
StateValue value = 3;

}

Expand Down Expand Up @@ -100,7 +100,7 @@ message QueueState {
* and the state name, which will be present in all types of code generation results as just underscores
* may be deleted and create unexpected collisions.
*/
message VirtualMapKey {
message StateKey {
oneof key {
SingletonType singleton = 1;

Expand Down Expand Up @@ -315,7 +315,7 @@ message VirtualMapKey {
* Note that `_I_` plays a role of a reliable separator between the service name
* and the state name, which will be present in all types of code generation results as just underscores
* may be deleted and create unexpected collisions.<br/>
* ID ranges for VirtualMapValue types:
* ID ranges for StateValue types:
* <ol>
* <li>0–7999: Core state entries. Reserved for all platform states
* (accounts, tokens, schedules, consensus topics, etc.).</li>
Expand All @@ -326,7 +326,7 @@ message VirtualMapKey {
* contents, etc.).</li>
* </ol>
*/
message VirtualMapValue {
message StateValue {
oneof value{
/**
* A state identifier for the next entity Identifier.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.hedera.hapi.platform.state.VirtualMapKey;
import com.hedera.hapi.platform.state.StateKey;
import com.hedera.pbj.runtime.ParseException;
import com.hedera.pbj.runtime.io.buffer.BufferedData;
import com.hedera.pbj.runtime.io.buffer.Bytes;
Expand Down Expand Up @@ -199,8 +199,8 @@ public void validateIndex(DeserializedSignedState deserializedState) {
incorrectBucketIndexList));
}

private static VirtualMapKey parseKey(Bytes keyBytes) throws ParseException {
return VirtualMapKey.PROTOBUF.parse(keyBytes);
private static StateKey parseKey(Bytes keyBytes) throws ParseException {
return StateKey.PROTOBUF.parse(keyBytes);
}

private static <T> void collectInfo(T info, CopyOnWriteArrayList<T> list) {
Expand All @@ -210,7 +210,7 @@ private static <T> void collectInfo(T info, CopyOnWriteArrayList<T> list) {
}

// Bucket entry path is not found in the leaf index
record StalePathInfo(long path, VirtualMapKey key) {
record StalePathInfo(long path, StateKey key) {
@Override
@NonNull
public String toString() {
Expand All @@ -219,7 +219,7 @@ public String toString() {
}

// Bucket entry path is in the leaf index, but leaf data cannot be loaded
private record NullLeafInfo(long path, VirtualMapKey key) {
private record NullLeafInfo(long path, StateKey key) {
@Override
@NonNull
public String toString() {
Expand All @@ -228,7 +228,7 @@ public String toString() {
}

// Bucket entry key doesn't match leaf key, leaf is loaded by entry path
record UnexpectedKeyInfo(long path, VirtualMapKey expectedKey, VirtualMapKey actualKey) {
record UnexpectedKeyInfo(long path, StateKey expectedKey, StateKey actualKey) {
@Override
@NonNull
public String toString() {
Expand All @@ -240,7 +240,7 @@ public String toString() {
}

// Bucket entry path doesn't match leaf path, leaf is loaded by entry path
private record PathMismatchInfo(long expectedPath, long actualPath, VirtualMapKey key) {
private record PathMismatchInfo(long expectedPath, long actualPath, StateKey key) {
@Override
@NonNull
public String toString() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
package com.hedera.statevalidation.validators.servicesstate;

import static com.hedera.statevalidation.validators.ParallelProcessingUtil.VALIDATOR_FORK_JOIN_POOL;
import static com.swirlds.state.merkle.StateUtils.extractVirtualMapKeyValueStateId;
import static com.swirlds.state.merkle.StateUtils.extractStateKeyValueStateId;
import static com.swirlds.state.merkle.StateUtils.stateIdFor;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;

import com.hedera.hapi.node.base.AccountID;
import com.hedera.hapi.node.state.token.Account;
import com.hedera.hapi.platform.state.VirtualMapValue;
import com.hedera.hapi.platform.state.StateValue;
import com.hedera.node.app.ids.EntityIdService;
import com.hedera.node.app.ids.ReadableEntityIdStoreImpl;
import com.hedera.node.app.service.token.impl.TokenServiceImpl;
Expand Down Expand Up @@ -74,12 +74,12 @@ void validate(DeserializedSignedState deserializedState, Report report) throws I
InterruptableConsumer<Pair<Bytes, Bytes>> handler = pair -> {
final Bytes keyBytes = pair.left();
final Bytes valueBytes = pair.right();
final int readKeyStateId = extractVirtualMapKeyValueStateId(keyBytes);
final int readValueStateId = extractVirtualMapKeyValueStateId(valueBytes);
final int readKeyStateId = extractStateKeyValueStateId(keyBytes);
final int readValueStateId = extractStateKeyValueStateId(valueBytes);
if ((readKeyStateId == targetStateId) && (readValueStateId == targetStateId)) {
try {
final VirtualMapValue virtualMapValue = VirtualMapValue.PROTOBUF.parse(valueBytes);
final Account account = virtualMapValue.value().as();
final StateValue stateValue = StateValue.PROTOBUF.parse(valueBytes);
final Account account = stateValue.value().as();
final long tinybarBalance = account.tinybarBalance();
assertTrue(tinybarBalance >= 0);
totalBalance.addAndGet(tinybarBalance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
package com.hedera.statevalidation.validators.servicesstate;

import static com.hedera.statevalidation.validators.ParallelProcessingUtil.VALIDATOR_FORK_JOIN_POOL;
import static com.swirlds.state.merkle.StateUtils.extractVirtualMapKeyValueStateId;
import static com.swirlds.state.merkle.StateUtils.extractStateKeyValueStateId;
import static com.swirlds.state.merkle.StateUtils.stateIdFor;
import static org.junit.jupiter.api.Assertions.*;

Expand All @@ -12,8 +12,8 @@
import com.hedera.hapi.node.state.token.Account;
import com.hedera.hapi.node.state.token.Token;
import com.hedera.hapi.node.state.token.TokenRelation;
import com.hedera.hapi.platform.state.VirtualMapKey;
import com.hedera.hapi.platform.state.VirtualMapValue;
import com.hedera.hapi.platform.state.StateKey;
import com.hedera.hapi.platform.state.StateValue;
import com.hedera.node.app.ids.EntityIdService;
import com.hedera.node.app.ids.ReadableEntityIdStoreImpl;
import com.hedera.node.app.service.token.impl.TokenServiceImpl;
Expand Down Expand Up @@ -79,18 +79,18 @@ void validate(DeserializedSignedState deserializedState, Report report) throws I
InterruptableConsumer<Pair<Bytes, Bytes>> handler = pair -> {
final Bytes keyBytes = pair.left();
final Bytes valueBytes = pair.right();
final int readKeyStateId = extractVirtualMapKeyValueStateId(keyBytes);
final int readValueStateId = extractVirtualMapKeyValueStateId(valueBytes);
final int readKeyStateId = extractStateKeyValueStateId(keyBytes);
final int readValueStateId = extractStateKeyValueStateId(valueBytes);
if ((readKeyStateId == targetStateId) && (readValueStateId == targetStateId)) {
try {
final VirtualMapKey parse = VirtualMapKey.PROTOBUF.parse(keyBytes);
final StateKey stateKey = StateKey.PROTOBUF.parse(keyBytes);

final EntityIDPair entityIDPair = parse.key().as();
final EntityIDPair entityIDPair = stateKey.key().as();
final AccountID accountId1 = entityIDPair.accountId();
final TokenID tokenId1 = entityIDPair.tokenId();

final VirtualMapValue virtualMapValue = VirtualMapValue.PROTOBUF.parse(valueBytes);
final TokenRelation tokenRelation = virtualMapValue.value().as();
final StateValue stateValue = StateValue.PROTOBUF.parse(valueBytes);
final TokenRelation tokenRelation = stateValue.value().as();
final AccountID accountId2 = tokenRelation.accountId();
final TokenID tokenId2 = tokenRelation.tokenId();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import com.hedera.hapi.node.base.SemanticVersion;
import com.hedera.hapi.platform.state.PlatformState;
import com.hedera.hapi.platform.state.VirtualMapValue;
import com.hedera.hapi.platform.state.StateValue;
import com.hedera.pbj.runtime.io.buffer.Bytes;
import com.swirlds.common.test.fixtures.Randotron;
import com.swirlds.merkledb.test.fixtures.MerkleDbTestUtils;
Expand Down Expand Up @@ -48,11 +48,11 @@ void setUp() {
"vm-" + WritablePlatformStateStoreTest.class.getSimpleName() + java.util.UUID.randomUUID();
virtualMap = VirtualMapUtils.createVirtualMap(virtualMapLabel, 1);

final Bytes key = StateUtils.getVirtualMapKeyForSingleton(PlatformStateService.NAME, PLATFORM_STATE_KEY);
final VirtualMapValue value = StateUtils.getVirtualMapValue(
final Bytes key = StateUtils.getStateKeyForSingleton(PlatformStateService.NAME, PLATFORM_STATE_KEY);
final StateValue value = StateUtils.getStateValue(
PlatformStateService.NAME, PLATFORM_STATE_KEY, toPbjPlatformState(randomPlatformState(randotron)));

virtualMap.put(key, value, VirtualMapValue.PROTOBUF);
virtualMap.put(key, value, StateValue.PROTOBUF);

when(writableStates.<PlatformState>getSingleton(PLATFORM_STATE_KEY))
.thenReturn(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
import static com.swirlds.state.StateChangeListener.StateType.SINGLETON;
import static com.swirlds.state.lifecycle.StateMetadata.computeLabel;
import static com.swirlds.state.merkle.StateUtils.decomposeLabel;
import static com.swirlds.state.merkle.StateUtils.getQueueStateVirtualMapValue;
import static com.swirlds.state.merkle.StateUtils.getVirtualMapKeyForQueue;
import static com.swirlds.state.merkle.StateUtils.getVirtualMapKeyForSingleton;
import static com.swirlds.state.merkle.StateUtils.getVirtualMapKeyValueBytes;
import static com.swirlds.state.merkle.StateUtils.getVirtualMapValue;
import static com.swirlds.state.merkle.StateUtils.getQueueStateValue;
import static com.swirlds.state.merkle.StateUtils.getStateKeyForQueue;
import static com.swirlds.state.merkle.StateUtils.getStateKeyForSingleton;
import static com.swirlds.state.merkle.StateUtils.getStateKeyValueBytes;
import static com.swirlds.state.merkle.StateUtils.getStateValue;
import static com.swirlds.state.merkle.VirtualMapState.VM_LABEL;
import static java.util.Objects.requireNonNull;

import com.hedera.hapi.platform.state.QueueState;
import com.hedera.hapi.platform.state.VirtualMapValue;
import com.hedera.hapi.platform.state.StateValue;
import com.hedera.pbj.runtime.io.buffer.Bytes;
import com.swirlds.base.time.Time;
import com.swirlds.base.utility.Pair;
Expand Down Expand Up @@ -1072,9 +1072,9 @@
final var value =
Objects.requireNonNull(originalStore.getValue(), "Null value is not expected here");

final Bytes key = getVirtualMapKeyForSingleton(serviceName, stateKey);
final VirtualMapValue virtualMapValue = getVirtualMapValue(serviceName, stateKey, value);
virtualMap.put(key, virtualMapValue, VirtualMapValue.PROTOBUF);
final Bytes key = getStateKeyForSingleton(serviceName, stateKey);
final StateValue stateValue = getStateValue(serviceName, stateKey, value);
virtualMap.put(key, stateValue, StateValue.PROTOBUF);

Check warning on line 1077 in platform-sdk/swirlds-state-impl/src/main/java/com/swirlds/state/merkle/MerkleStateRoot.java

View check run for this annotation

Codecov / codecov/patch

platform-sdk/swirlds-state-impl/src/main/java/com/swirlds/state/merkle/MerkleStateRoot.java#L1075-L1077

Added lines #L1075 - L1077 were not covered by tests

long migrationTimeMs = System.currentTimeMillis() - migrationStartTime;
logger.info(
Expand Down Expand Up @@ -1112,7 +1112,7 @@
}

private static void validateSingletonStateMigrated(VirtualMap virtualMap, String serviceName, String stateKey) {
assert virtualMap.containsKey(getVirtualMapKeyForSingleton(serviceName, stateKey));
assert virtualMap.containsKey(getStateKeyForSingleton(serviceName, stateKey));
}

private void migrateQueueStates(
Expand Down Expand Up @@ -1154,18 +1154,18 @@
virtualMapRef.set(currentMap);
}

final Bytes key = getVirtualMapKeyForQueue(serviceName, stateKey, tail++);
final VirtualMapValue virtualMapValue = getVirtualMapValue(serviceName, stateKey, value);
virtualMapRef.get().put(key, virtualMapValue, VirtualMapValue.PROTOBUF);
final Bytes key = getStateKeyForQueue(serviceName, stateKey, tail++);
final StateValue stateValue = getStateValue(serviceName, stateKey, value);
virtualMapRef.get().put(key, stateValue, StateValue.PROTOBUF);

Check warning on line 1159 in platform-sdk/swirlds-state-impl/src/main/java/com/swirlds/state/merkle/MerkleStateRoot.java

View check run for this annotation

Codecov / codecov/patch

platform-sdk/swirlds-state-impl/src/main/java/com/swirlds/state/merkle/MerkleStateRoot.java#L1157-L1159

Added lines #L1157 - L1159 were not covered by tests
}

final var queueState = new QueueState(head, tail);
virtualMapRef
.get()
.put(
getVirtualMapKeyForSingleton(serviceName, stateKey),
getQueueStateVirtualMapValue(queueState),
VirtualMapValue.PROTOBUF);
getStateKeyForSingleton(serviceName, stateKey),
getQueueStateValue(queueState),

Check warning on line 1167 in platform-sdk/swirlds-state-impl/src/main/java/com/swirlds/state/merkle/MerkleStateRoot.java

View check run for this annotation

Codecov / codecov/patch

platform-sdk/swirlds-state-impl/src/main/java/com/swirlds/state/merkle/MerkleStateRoot.java#L1166-L1167

Added lines #L1166 - L1167 were not covered by tests
StateValue.PROTOBUF);

long migrationTimeMs = System.currentTimeMillis() - migrationStartTime;
logger.info(
Expand Down Expand Up @@ -1209,11 +1209,11 @@
private static void validateQueueStateMigrated(
VirtualMap virtualMap, String serviceName, String stateKey, long head, long tail) {
// Validate Queue State object
assert virtualMap.containsKey(getVirtualMapKeyForSingleton(serviceName, stateKey));
assert virtualMap.containsKey(getStateKeyForSingleton(serviceName, stateKey));

// Validate Queue State values
for (long i = head; i < tail; i++) {
assert virtualMap.containsKey(getVirtualMapKeyForQueue(serviceName, stateKey, i));
assert virtualMap.containsKey(getStateKeyForQueue(serviceName, stateKey, i));
}
}

Expand Down Expand Up @@ -1244,8 +1244,8 @@
older.release();
virtualMapRef.set(currentMap);
}
final Bytes keyBytes = getVirtualMapKeyValueBytes(serviceName, stateKey, pair.key());
final Bytes valueBytes = getVirtualMapKeyValueBytes(serviceName, stateKey, pair.value());
final Bytes keyBytes = getStateKeyValueBytes(serviceName, stateKey, pair.key());
final Bytes valueBytes = getStateKeyValueBytes(serviceName, stateKey, pair.value());

Check warning on line 1248 in platform-sdk/swirlds-state-impl/src/main/java/com/swirlds/state/merkle/MerkleStateRoot.java

View check run for this annotation

Codecov / codecov/patch

platform-sdk/swirlds-state-impl/src/main/java/com/swirlds/state/merkle/MerkleStateRoot.java#L1247-L1248

Added lines #L1247 - L1248 were not covered by tests
virtualMapRef.get().putBytes(keyBytes, valueBytes);
};

Expand Down Expand Up @@ -1310,7 +1310,7 @@
while (merkleNodeMerkleIterator.hasNext()) {
MerkleNode next = merkleNodeMerkleIterator.next();
if (next instanceof VirtualLeafNode virtualLeafNode) {
final var keyBytes = getVirtualMapKeyValueBytes(serviceName, stateKey, virtualLeafNode.getKey());
final var keyBytes = getStateKeyValueBytes(serviceName, stateKey, virtualLeafNode.getKey());

Check warning on line 1313 in platform-sdk/swirlds-state-impl/src/main/java/com/swirlds/state/merkle/MerkleStateRoot.java

View check run for this annotation

Codecov / codecov/patch

platform-sdk/swirlds-state-impl/src/main/java/com/swirlds/state/merkle/MerkleStateRoot.java#L1313

Added line #L1313 was not covered by tests
assert virtualMap.containsKey(keyBytes);
}
}
Expand Down
Loading
Loading