Skip to content
Merged
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
1 change: 1 addition & 0 deletions ledger/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ dependencies {
implementation group: 'com.github.everit-org.json-schema', name: 'org.everit.json.schema', version: '1.14.4'

testImplementation group: 'com.scalar-labs', name: 'scalardb-schema-loader', version: "${scalarDbVersion}"
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-params', version: "${junitVersion}"

// for Error Prone
errorprone "com.google.errorprone:error_prone_core:${errorproneVersion}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,17 @@ public List<AssetProof> commit() {
if (snapshot.hasWriteSet()) {
puts = assetComposer.compose(snapshot, request);

if (config.isTxStateManagementEnabled()) {
stateManager.putCommit(transaction, transaction.getId());
}

transaction.put(puts);

if (!config.isDirectAssetAccessEnabled()) {
metadata.put(snapshot.getWriteSet().values());
}
}
Comment on lines 136 to 141

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Moving the transaction.put call outside the if block could lead to unexpected behavior if config.isTxStateManagementEnabled() is true but snapshot.hasWriteSet() is false. In such cases, the transaction state would be updated without any actual data being written, potentially causing inconsistencies. This should be reverted to ensure the transaction state is only updated when there are writes to the snapshot.

        if (config.isTxStateManagementEnabled()) {
          stateManager.putCommit(transaction, transaction.getId());
        }

        transaction.put(puts);

        if (!config.isDirectAssetAccessEnabled()) {
          metadata.put(snapshot.getWriteSet().values());


if (config.isTxStateManagementEnabled()) {
stateManager.putCommit(transaction, transaction.getId());
}

transaction.commit();
} catch (CrudConflictException e) {
throw new ConflictException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
Expand Down Expand Up @@ -466,6 +468,7 @@ public void commit_EmptySnapshotGiven_ShouldDoNothing()
CrudException {
// Arrange
when(config.isDirectAssetAccessEnabled()).thenReturn(false);
when(config.isTxStateManagementEnabled()).thenReturn(false);

// Act
ledger.commit();
Expand All @@ -482,6 +485,7 @@ public void commit_EmptySnapshotGivenAndDirectAssetAccessEnabled_ShouldDoNothing
CrudException {
// Arrange
when(config.isDirectAssetAccessEnabled()).thenReturn(true);
when(config.isTxStateManagementEnabled()).thenReturn(false);

// Act
ledger.commit();
Expand Down Expand Up @@ -741,12 +745,14 @@ public void commit_CommitExceptionThrownInCommit_ShouldThrowDatabaseException()
assertThat(proofs).containsOnly(proof);
}

@Test
public void commit_TxStateManagementEnabled_ShouldPutWithStateManager()
@ParameterizedTest
@ValueSource(booleans = {true, false})
public void commit_WriteTransactionGiven_ShouldPutWithStateManagerAccordingToConfig(
boolean txStateManagementEnabled)
throws CrudException, CommitException,
com.scalar.db.exception.transaction.UnknownTransactionStatusException {
// Arrange
when(config.isTxStateManagementEnabled()).thenReturn(true);
when(config.isTxStateManagementEnabled()).thenReturn(txStateManagementEnabled);
snapshot.put(ANY_ID, asset);
snapshot.put(ANY_ID, ANY_DATA);
doNothing().when(transaction).put(any(List.class));
Expand All @@ -758,32 +764,40 @@ public void commit_TxStateManagementEnabled_ShouldPutWithStateManager()
ledger.commit();

// Assert
verify(stateManager).putCommit(transaction, ANY_NONCE);
if (txStateManagementEnabled) {
verify(stateManager).putCommit(transaction, ANY_NONCE);
} else {
verify(stateManager, never()).putCommit(any(DistributedTransaction.class), anyString());
}
verify(transaction).put(any(List.class));
verify(transaction).put(any(Put.class));
verify(transaction).commit();
}

@Test
public void commit_TxStateManagementDisabled_ShouldNotPutWithStateManager()
@ParameterizedTest
@ValueSource(booleans = {true, false})
public void commit_ReadOnlyTransactionGiven_ShouldPutWithStateManagerAccordingToConfig(
boolean txStateManagementEnabled)
throws CrudException, CommitException,
com.scalar.db.exception.transaction.UnknownTransactionStatusException {
// Arrange
when(config.isTxStateManagementEnabled()).thenReturn(false);
snapshot.put(ANY_ID, asset);
snapshot.put(ANY_ID, ANY_DATA);
doNothing().when(transaction).put(any(List.class));
doNothing().when(transaction).put(any(Put.class));
when(config.isTxStateManagementEnabled()).thenReturn(txStateManagementEnabled);
when(config.isDirectAssetAccessEnabled()).thenReturn(false);
when(transaction.getId()).thenReturn(ANY_NONCE);
doNothing().when(stateManager).putCommit(any(DistributedTransaction.class), anyString());
snapshot.put(ANY_ID, asset);

// Act
ledger.commit();

// Assert
verify(stateManager, never()).putCommit(transaction, ANY_NONCE);
verify(transaction).put(any(List.class));
verify(transaction).put(any(Put.class));
if (txStateManagementEnabled) {
verify(stateManager).putCommit(transaction, ANY_NONCE);
} else {
verify(stateManager, never()).putCommit(any(DistributedTransaction.class), anyString());
}
verify(transaction, never()).put(any(List.class));
verify(transaction, never()).put(any(Put.class));
Comment on lines +799 to +800

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The assertions verify(transaction, never()).put(any(List.class)) and verify(transaction, never()).put(any(Put.class)) are checking that put is never called on the transaction when txStateManagementEnabled is false. However, the test setup includes snapshot.put(ANY_ID, asset), which means there's data to be written. This contradicts the intention of testing a read-only transaction and could lead to incorrect test results. The snapshot.put call should be removed or conditioned on txStateManagementEnabled to accurately test the read-only scenario.

Suggested change
verify(transaction, never()).put(any(List.class));
verify(transaction, never()).put(any(Put.class));
if (txStateManagementEnabled) {
snapshot.put(ANY_ID, asset);
}

verify(transaction).commit();
}

Expand Down