-
Notifications
You must be signed in to change notification settings - Fork 143
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
refactor: adapt StatsSigningTestingTool to work with Bytes wrapper for transactions #17144
base: main
Are you sure you want to change the base?
refactor: adapt StatsSigningTestingTool to work with Bytes wrapper for transactions #17144
Conversation
Signed-off-by: Mustafa Uzun <[email protected]>
…r transactions Signed-off-by: Ivan Kavaldzhiev <[email protected]>
…igningTestingTool-to-work-with-Bytes
Signed-off-by: Ivan Kavaldzhiev <[email protected]>
…ransactions' into 16871-adapt-StatsSigningTestingTool-to-work-with-Bytes # Conflicts: # platform-sdk/platform-apps/tests/StatsSigningTestingTool/src/main/java/com/swirlds/demo/stats/signing/StatsSigningTestingToolState.java Signed-off-by: Ivan Kavaldzhiev <[email protected]>
…ransactions' into 16871-adapt-StatsSigningTestingTool-to-work-with-Bytes
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #17144 +/- ##
============================================
+ Coverage 67.41% 67.60% +0.18%
- Complexity 22063 22125 +62
============================================
Files 2585 2585
Lines 96408 96440 +32
Branches 10071 10075 +4
============================================
+ Hits 64992 65195 +203
+ Misses 27698 27511 -187
- Partials 3718 3734 +16
|
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferencesCodacy stopped sending the deprecated coverage status on June 5th, 2024. Learn more |
@@ -313,4 +315,9 @@ public PlatformMerkleStateRoot newMerkleStateRoot() { | |||
public BasicSoftwareVersion getSoftwareVersion() { | |||
return softwareVersion; | |||
} | |||
|
|||
@Override | |||
public Bytes encodeSystemTransaction(@NonNull StateSignatureTransaction transaction) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add final
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
|
||
if (areTransactionBytesSystemOnes((ConsensusTransaction) transaction)) { | ||
stateSignatureTransactions.accept( | ||
new ScopedSystemTransaction(event.getCreatorId(), event.getSoftwareVersion(), transaction)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can return after this, since the application should not do anything with the system transactions other than invoke the callback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. Fixed
round.forEachTransaction(this::handleTransaction); | ||
|
||
round.forEachEventTransaction((event, transaction) -> { | ||
final var transactionWithSystemBytes = handleTransaction(transaction); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not check if it is a system transaction here in the lambda before invoking handleTransaction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
…igningTestingTool-to-work-with-Bytes # Conflicts: # platform-sdk/platform-apps/demos/CryptocurrencyDemo/src/main/java/com/swirlds/demo/crypto/CryptocurrencyDemoState.java # platform-sdk/platform-apps/demos/HelloSwirldDemo/src/main/java/com/swirlds/demo/hello/HelloSwirldDemoState.java # platform-sdk/platform-apps/demos/StatsDemo/src/main/java/com/swirlds/demo/stats/StatsDemoState.java # platform-sdk/platform-apps/tests/AddressBookTestingTool/src/main/java/com/swirlds/demo/addressbook/AddressBookTestingToolState.java # platform-sdk/platform-apps/tests/ConsistencyTestingTool/src/main/java/com/swirlds/demo/consistency/ConsistencyTestingToolState.java # platform-sdk/platform-apps/tests/ISSTestingTool/src/main/java/com/swirlds/demo/iss/ISSTestingToolState.java # platform-sdk/platform-apps/tests/MigrationTestingTool/src/main/java/com/swirlds/demo/migration/MigrationTestingToolState.java # platform-sdk/platform-apps/tests/PlatformTestingTool/src/main/java/com/swirlds/demo/platform/PlatformTestingToolState.java # platform-sdk/platform-apps/tests/StatsSigningTestingTool/src/main/java/com/swirlds/demo/stats/signing/StatsSigningTestingToolState.java # platform-sdk/platform-apps/tests/StressTestingTool/src/main/java/com/swirlds/demo/stress/StressTestingToolState.java # platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/state/PlatformMerkleStateRoot.java # platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/SwirldState.java # platform-sdk/swirlds-platform-core/src/test/java/com/swirlds/platform/turtle/runner/TurtleTestingToolState.java # platform-sdk/swirlds-platform-core/src/testFixtures/java/com/swirlds/platform/test/fixtures/state/BlockingSwirldState.java Signed-off-by: Ivan Kavaldzhiev <[email protected]>
Signed-off-by: Ivan Kavaldzhiev <[email protected]>
Signed-off-by: Ivan Kavaldzhiev <[email protected]>
private boolean areTransactionBytesSystemOnes(final ConsensusTransaction transaction) { | ||
// We have maximum allocation of 100 bytes for the transaction + 10 bytes for the preamble size in | ||
// TransactionCodec | ||
// + 64 bytes for the maximum public key size + 64 bytes for the maximum signature size + 12 bytes for 3 | ||
// integers | ||
final var maximumSignedEncodedTransactionSize = 100 + 10 + 64 + 64 + 12; | ||
return transaction.getApplicationTransaction().length() > maximumSignedEncodedTransactionSize; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this app has a configurable transaction size, so size cannot be used to differentiate between system and app
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. This approach wasn't future proof. I changed the logic for differentiation. It can be re-reviewd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed file platform-sdk/platform-apps/tests/StatsSigningTestingTool/build.gradle.kts
and approved.
…ingTestingTool-to-work-with-Bytes
Signed-off-by: Ivan Kavaldzhiev <[email protected]>
Signed-off-by: Ivan Kavaldzhiev <[email protected]>
final var transactionPool = transactionPoolSupplier.get(); | ||
|
||
// Check the data length size is the expected size based on the transactionSize property. | ||
// If it is not, then the transaction is a system one. | ||
if (TransactionCodec.txIsSigned(transactionBytes)) { | ||
// Data length can be read directly from the extracted signature | ||
final var signature = TransactionCodec.extractSignature(transactionBytes); | ||
return signature.getMessageLength() != transactionPool.getTransactionSize(); | ||
} else { | ||
// Data length value can be read from the transaction bytes using an offset | ||
final ByteBuffer wrapper = | ||
ByteBuffer.wrap(transactionBytes.toByteArray()).position(21); | ||
final byte dataLength = wrapper.get(); | ||
return dataLength != transactionPool.getTransactionSize(); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this does not work if they happen to be the same size, so we need a definitive way of differentiating them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added additional logic that follows the transaction bytes structure from TransactionCodec
. Now the algorithm checks if we have the correct size for the different segments on the correct positions and whether we have any bytes left after we load the data segment
(which is the last one), using the data length
value before it. I believe it will be very unlikely to have a system transaction that will cover all the additional checks I've added.
Another approach, which will be more harming for the performance, is trying to parse the transactions bytes to a StateSignatureTransaction
pbj type for each incoming transaction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while this makes it very unlikely to confuse the two, it is still theoretically possible. so why not make it simpler and be 100% sure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a simpler approach for filtering system transactions.
Signed-off-by: Ivan Kavaldzhiev <[email protected]>
…ingTestingTool-to-work-with-Bytes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review applies only to platform-sdk/platform-apps/tests/StatsSigningTestingTool/build.gradle.kts
. Approved.
…ingTestingTool-to-work-with-Bytes
…ool-to-work-with-Bytes' into 16871-adapt-StatsSigningTestingTool-to-work-with-Bytes
…ingTestingTool-to-work-with-Bytes # Conflicts: # platform-sdk/platform-apps/tests/StatsSigningTestingTool/src/main/java/com/swirlds/demo/stats/signing/StatsSigningTestingToolMain.java # platform-sdk/platform-apps/tests/StatsSigningTestingTool/src/main/java/com/swirlds/demo/stats/signing/StatsSigningTestingToolState.java Signed-off-by: Ivan Kavaldzhiev <[email protected]>
… the transaction itself Signed-off-by: Ivan Kavaldzhiev <[email protected]>
…ingTestingTool-to-work-with-Bytes
Signed-off-by: Ivan Kavaldzhiev <[email protected]>
Signed-off-by: Ivan Kavaldzhiev <[email protected]>
…ingTestingTool-to-work-with-Bytes
Signed-off-by: Ivan Kavaldzhiev <[email protected]>
* @param transaction the transaction to check | ||
* @return true if the transaction bytes are system ones, false otherwise | ||
*/ | ||
private boolean areTransactionBytesSystemOnes(final Transaction transaction) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add nullity annotation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
} | ||
|
||
private void consumeSystemTransaction( | ||
final Transaction transaction, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nullity for all parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
…ingTestingTool-to-work-with-Bytes
...tencyTestingTool/src/main/java/com/swirlds/demo/consistency/ConsistencyTestingToolState.java
Outdated
Show resolved
Hide resolved
...tencyTestingTool/src/main/java/com/swirlds/demo/consistency/ConsistencyTestingToolState.java
Outdated
Show resolved
Hide resolved
…ation transactions Signed-off-by: Ivan Kavaldzhiev <[email protected]>
…ingTestingTool-to-work-with-Bytes # Conflicts: # platform-sdk/swirlds-platform-core/src/main/java/com/swirlds/platform/system/SwirldMain.java Signed-off-by: Ivan Kavaldzhiev <[email protected]>
Signed-off-by: Ivan Kavaldzhiev <[email protected]>
Signed-off-by: Ivan Kavaldzhiev <[email protected]>
public Bytes encodeSystemTransaction(@NonNull final StateSignatureTransaction transaction) { | ||
final String stateSignatureMarker = STATE_SIGNATURE_MARKER; | ||
final int markerSize = stateSignatureMarker.length(); | ||
final byte[] parsedStateSignatureTransaction = | ||
StateSignatureTransaction.PROTOBUF.toBytes(transaction).toByteArray(); | ||
final int bufferCapacity = Integer.BYTES + markerSize + parsedStateSignatureTransaction.length; | ||
|
||
final ByteBuffer buffer = ByteBuffer.allocate(bufferCapacity); | ||
buffer.putInt(markerSize); | ||
buffer.put(stateSignatureMarker.getBytes()); | ||
buffer.put(parsedStateSignatureTransaction); | ||
|
||
return Bytes.wrap(buffer.array()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why put a string as a marker? a byte would be enough.
also, you can use var out = new WritableStreamingData(new ByteArrayOutputStream))
to write the marker first and then the PBJ record with StateSignatureTransaction.PROTOBUF.write(transaction, out)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
Signed-off-by: Ivan Kavaldzhiev <[email protected]>
Description:
This PR updates StatsSigningTestingTool to work with the new Bytes format of system transactions.
Related issue(s):
Fixes #16871
Notes for reviewer:
Checklist