Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: hiero-ledger/hiero-block-node
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1c0a0ffc77c53a9691a419d2bb424572e64d03ec
Choose a base ref
..
head repository: hiero-ledger/hiero-block-node
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: ad1fe3307f632a85ac6c4d66db394add057c1d5d
Choose a head ref
Showing with 1,020 additions and 398 deletions.
  1. +1 −1 .github/workflows/helm-charts.yaml
  2. +1 −1 .github/workflows/pr-checks.yaml
  3. +2 −2 .github/workflows/release-push-image.yaml
  4. +3 −3 .github/workflows/zxc-verify-docker-build-determinism.yaml
  5. +1 −1 .github/workflows/zxc-verify-gradle-build-determinism.yaml
  6. +4 −4 hiero-dependency-versions/build.gradle.kts
  7. +13 −9 server/docs/design/Addenda/BlockPersistenceTaskBasedWriter.md
  8. +33 −0 server/docs/design/design-doc-template.md
  9. +5 −0 server/docs/design/how-to-design-doc.md
  10. +2 −0 server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java
  11. +65 −0 server/src/main/java/com/hedera/block/server/ack/AckBlockStatus.java
  12. +28 −0 server/src/main/java/com/hedera/block/server/ack/AckHandler.java
  13. +129 −0 server/src/main/java/com/hedera/block/server/ack/AckHandlerImpl.java
  14. +35 −0 server/src/main/java/com/hedera/block/server/ack/AckHandlerInjectionModule.java
  15. +57 −0 server/src/main/java/com/hedera/block/server/block/BlockInfo.java
  16. +18 −3 server/src/main/java/com/hedera/block/server/notifier/Notifier.java
  17. +58 −43 server/src/main/java/com/hedera/block/server/notifier/NotifierImpl.java
  18. +5 −5 server/src/main/java/com/hedera/block/server/persistence/PersistenceInjectionModule.java
  19. +16 −9 server/src/main/java/com/hedera/block/server/persistence/StreamPersistenceHandlerImpl.java
  20. +3 −9 server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsLocalDirWriter.java
  21. +5 −5 .../src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsLocalFileAsyncWriter.java
  22. +6 −4 server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsLocalFileWriter.java
  23. +4 −3 server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockWriter.java
  24. +2 −1 server/src/main/java/com/hedera/block/server/persistence/storage/write/LocalBlockWriter.java
  25. +15 −7 server/src/main/java/com/hedera/block/server/persistence/storage/write/NoOpBlockWriter.java
  26. +5 −5 ...com/hedera/block/server/persistence/storage/write/factory/BlockAsLocalFileAsyncWriterFactory.java
  27. +0 −28 server/src/main/java/com/hedera/block/server/producer/Util.java
  28. +4 −2 server/src/main/java/com/hedera/block/server/verification/VerificationInjectionModule.java
  29. +15 −18 server/src/main/java/com/hedera/block/server/verification/service/BlockVerificationServiceImpl.java
  30. +4 −2 server/src/main/java/com/hedera/block/server/verification/signature/SignatureVerifierDummy.java
  31. +1 −0 server/src/main/java/module-info.java
  32. +5 −1 server/src/test/java/com/hedera/block/server/grpc/BlockAccessServiceTest.java
  33. +176 −0 server/src/test/java/com/hedera/block/server/manager/AckHandlerImplTest.java
  34. +43 −0 server/src/test/java/com/hedera/block/server/manager/AckHandlerInjectionModuleTest.java
  35. +9 −5 server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java
  36. +32 −53 server/src/test/java/com/hedera/block/server/notifier/NotifierImplTest.java
  37. +46 −29 server/src/test/java/com/hedera/block/server/pbj/PbjBlockStreamServiceIntegrationTest.java
  38. +12 −3 server/src/test/java/com/hedera/block/server/persistence/PersistenceInjectionModuleTest.java
  39. +10 −6 server/src/test/java/com/hedera/block/server/persistence/StreamPersistenceHandlerImplTest.java
  40. +11 −4 server/src/test/java/com/hedera/block/server/persistence/storage/read/BlockAsLocalDirReaderTest.java
  41. +10 −2 ...er/src/test/java/com/hedera/block/server/persistence/storage/read/BlockAsLocalFileReaderTest.java
  42. +8 −1 .../src/test/java/com/hedera/block/server/persistence/storage/remove/BlockAsLocalDirRemoverTest.java
  43. +17 −11 ...er/src/test/java/com/hedera/block/server/persistence/storage/write/BlockAsLocalDirWriterTest.java
  44. +38 −13 ...r/src/test/java/com/hedera/block/server/persistence/storage/write/BlockAsLocalFileWriterTest.java
  45. +15 −8 server/src/test/java/com/hedera/block/server/persistence/storage/write/NoOpBlockWriterTest.java
  46. +8 −11 server/src/test/java/com/hedera/block/server/util/PbjProtoTestUtils.java
  47. +9 −81 server/src/test/java/com/hedera/block/server/verification/BlockVerificationServiceImplTest.java
  48. +7 −3 server/src/test/java/com/hedera/block/server/verification/VerificationInjectionModuleTest.java
  49. +22 −2 server/src/test/java/com/hedera/block/server/verification/signature/SignatureVerifierDummyTest.java
  50. +2 −0 suites/src/main/java/com/hedera/block/suites/grpc/positive/PositiveEndpointBehaviourTests.java
2 changes: 1 addition & 1 deletion .github/workflows/helm-charts.yaml
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ jobs:
version: v3.14.4

- name: Setup Python
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
with:
python-version: "3.x"
check-latest: true
2 changes: 1 addition & 1 deletion .github/workflows/pr-checks.yaml
Original file line number Diff line number Diff line change
@@ -89,6 +89,6 @@ jobs:
run: ${GRADLE_EXEC} check

- name: Upload coverage report
uses: codecov/codecov-action@0da7aa657d958d32c117fc47e1f977e7524753c7 # v5.3.0
uses: codecov/codecov-action@13ce06bfc6bbe3ecf90edbbf1bc32fe5978ca1d3 # v5.3.1
with:
token: ${{ secrets.CODECOV_TOKEN }}
4 changes: 2 additions & 2 deletions .github/workflows/release-push-image.yaml
Original file line number Diff line number Diff line change
@@ -101,7 +101,7 @@ jobs:
echo "SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}" >> $GITHUB_ENV
- name: Server - Build and push image
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
with:
context: ./server/docker
file: ./server/docker/Dockerfile
@@ -123,7 +123,7 @@ jobs:
./gradlew :simulator:copyDependenciesFolders
- name: Simulator - Build and push image
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
with:
context: ./simulator/build/docker
file: ./simulator/docker/Dockerfile
6 changes: 3 additions & 3 deletions .github/workflows/zxc-verify-docker-build-determinism.yaml
Original file line number Diff line number Diff line change
@@ -177,7 +177,7 @@ jobs:
echo "VERSION=${VERSION}" >> $GITHUB_ENV
- name: Build Docker Image
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
env:
SOURCE_DATE_EPOCH: ${{ steps.commit.outputs.source-date }}
if: ${{ steps.baseline.outputs.exists == 'false' && !failure() && !cancelled() }}
@@ -241,7 +241,7 @@ jobs:
ref: ${{ inputs.ref }}

- name: Setup Python
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
with:
python-version: 3.9

@@ -318,7 +318,7 @@ jobs:
echo "VERSION=${VERSION}" >> $GITHUB_ENV
- name: Build Docker Image
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
uses: docker/build-push-action@ca877d9245402d1537745e0e356eab47c3520991 # v6.13.0
env:
SOURCE_DATE_EPOCH: ${{ needs.generate-baseline.outputs.source-date }}
with:
2 changes: 1 addition & 1 deletion .github/workflows/zxc-verify-gradle-build-determinism.yaml
Original file line number Diff line number Diff line change
@@ -162,7 +162,7 @@ jobs:
ref: ${{ inputs.ref }}

- name: Setup Python
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
with:
python-version: 3.9

8 changes: 4 additions & 4 deletions hiero-dependency-versions/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -10,10 +10,10 @@ dependencies { api(platform("com.google.cloud:libraries-bom:26.53.0")) }

dependencies.constraints {
val daggerVersion = "2.55"
val grpcIoVersion = "1.69.1"
val grpcIoVersion = "1.70.0"
val helidonVersion = "4.1.6"
val pbjVersion = "0.9.12"
val protobufVersion = "4.28.2"
val protobufVersion = "4.29.3"
val swirldsVersion = "0.58.1"

api("com.github.luben:zstd-jni:1.5.6-8") { because("com.github.luben.zstd_jni") }
@@ -23,7 +23,7 @@ dependencies.constraints {
api("com.google.auto.service:auto-service-annotations:1.1.1") {
because("com.google.auto.service")
}
api("com.google.guava:guava:33.3.1-jre") { because("com.google.common") }
api("com.google.guava:guava:33.4.0-jre") { because("com.google.common") }
api("com.google.j2objc:j2objc-annotations:3.0.0") { because("com.google.j2objc.annotations") }
api("com.google.protobuf:protobuf-java-util:$protobufVersion") {
because("com.google.protobuf.util")
@@ -46,7 +46,7 @@ dependencies.constraints {
api("io.helidon.webserver:helidon-webserver:$helidonVersion") {
because("io.helidon.webserver")
}
api("org.jetbrains:annotations:26.0.1") { because("org.jetbrains.annotations") }
api("org.jetbrains:annotations:26.0.2") { because("org.jetbrains.annotations") }

// gRPC dependencies
api("io.grpc:grpc-api:$grpcIoVersion") { because("io.grpc") }
22 changes: 13 additions & 9 deletions server/docs/design/Addenda/BlockPersistenceTaskBasedWriter.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
# Task Based Block File Writer

## General Approach

Upon receiving an event, the Handler checks if the first item is a Header, or
the last item is a Block Proof. Note, this assumes an event is a list of
block items, and conforms to the general contract for publishing data to
the block node.
Upon receiving an event, the Handler performs the following actions.
1. If the first item is a Block Header, create a new writer task, get the
transfer queue, assign the transfer queue to the _current transfer queue_,
and submit the new writer task to the _completion service_.
transfer queue, assign the transfer queue to the _current transfer queue_,
and submit the new writer task to the _completion service_.
1. Send all items to the _current transfer queue_.
1. If the last item is a Block Proof, assign null to the
_current transfer queue_.
_current transfer queue_.
1. While the _completion service_ returns non-null when _polled_, get the
result and notify (or publish a _persistence result_) appropriately.
result and notify (or publish a _persistence result_) appropriately.

> Note, _writers_ should implement `Callable` to make this process simpler.
## Structure Diagram

![Task Persistence](../assets/Task-Persistence.svg)

## Expected Behavior

The Handler is relatively simple. The Handler simply checks the input, and
does three things. If there is a header (this starts a new block), create
a new writer and obtain the transfer queue. In _all_ cases, add every item
in the list to the current transfer queue. If there is a block proof (ending
the block), assign null to the current transfer queue.

### Considerations

1. What if a list both starts with a block header and ends with a block proof?
* By performing the steps in order (header, send items, proof), this is
handled. The writer will get header, items between, and proof at the end.
@@ -35,10 +40,10 @@ the block), assign null to the current transfer queue.
* If a new block header arrives while the _current transfer queue_ is not
null, then the Handler can add a `null` to the transfer queue before
creating a new writer as usual.
* The _writer_ will respond to a null item by removing the partially
written block and completing exceptionally.
* When the _completion service_ is polled for results; that result,
when available, will result in an error _persistence result_.
* The _writer_ will respond to a null item by removing the partially
written block and completing exceptionally.
* When the _completion service_ is polled for results; that result,
when available, will result in an error _persistence result_.
3. What if writers finish out of order?
* This should be extremely rare, as blocks _must_ arrive in order
* The _persistence result_ for the blocks will be published out of order
@@ -68,4 +73,3 @@ the block), assign null to the current transfer queue.
* We will need to add _reset_ capability to all services when we get to
adding handling for the _behind_, _restart_, and _recover_ conditions
to the block node.

33 changes: 33 additions & 0 deletions server/docs/design/design-doc-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Design Document Template

## Table of Contents

1. [Purpose](#purpose)
2. [Goals](#goals)
3. [Terms](#terms)
4. [Entities](#entities)
5. [Design](#design)
6. [Sequence Diagram](#sequence-diagram)
7. [Configuration](#configuration)
8. [Metrics](#metrics)
9. [Exceptions](#exceptions)

## Purpose

## Goals

## Terms

## Entities

## Design

## Sequence Diagram

### Consider using mermaid to generate the sequence diagram

## Configuration

## Metrics

## Exceptions
5 changes: 5 additions & 0 deletions server/docs/design/how-to-design-doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## How to start a design doc

1) Copy the [template](design-doc-template.md) from `docs/design/design-doc-template.md` to a new markdown file.
2) Take a look at [this example](block-verification.md) `docs/design/block-verification.md` for the detail level and tone.
3) Fill out the template with your design.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
package com.hedera.block.server;

import com.hedera.block.server.ack.AckHandlerInjectionModule;
import com.hedera.block.server.config.ConfigInjectionModule;
import com.hedera.block.server.health.HealthInjectionModule;
import com.hedera.block.server.mediator.MediatorInjectionModule;
@@ -29,6 +30,7 @@
MetricsInjectionModule.class,
PbjInjectionModule.class,
VerificationInjectionModule.class,
AckHandlerInjectionModule.class
})
public interface BlockNodeAppInjectionComponent {
/**
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// SPDX-License-Identifier: Apache-2.0
package com.hedera.block.server.ack;

import java.util.concurrent.atomic.AtomicBoolean;

/**
* A simple block status object that:
* - Uses volatile booleans for 'persisted' and 'verified' (set once, from false to true).
* - Uses an AtomicBoolean 'ackSent' for lock-free compare-and-set if a block has been ACKed.
*/
public class AckBlockStatus {

private volatile boolean persisted = false;
private volatile boolean verified = false;

/** Flag that tracks whether this block has been ACKed. */
private final AtomicBoolean ackSent = new AtomicBoolean(false);

/**
* Marks this block as persisted.
* This is a "set once" transition from false -> true (idempotent if called again).
*/
public void setPersisted() {
persisted = true;
}

/**
* Marks this block as verified.
* This is a "set once" transition from false -> true (idempotent if called again).
*/
public void setVerified() {
verified = true;
}

/**
* Atomically marks this block as ACKed if not already done.
*
* @return true if this call successfully set 'ackSent' from false -> true,
* false if 'ackSent' was already true.
*/
public boolean markAckSentIfNotAlready() {
return ackSent.compareAndSet(false, true);
}

/**
* @return true if persisted = true
*/
public boolean isPersisted() {
return persisted;
}

/**
* @return true if verified = true
*/
public boolean isVerified() {
return verified;
}

/**
* @return true if 'ackSent' has already been set
*/
public boolean isAckSent() {
return ackSent.get();
}
}
28 changes: 28 additions & 0 deletions server/src/main/java/com/hedera/block/server/ack/AckHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: Apache-2.0
package com.hedera.block.server.ack;

import com.hedera.pbj.runtime.io.buffer.Bytes;
import edu.umd.cs.findbugs.annotations.NonNull;

/**
* Interface for managing blocks, their persistence, verification, and failure.
* Responsible for sending Block Acknowledgements to the producer.
*/
public interface AckHandler {

/**
* Called when we receive a "persistence" event for the given blockNumber.
*/
void blockPersisted(long blockNumber);

/**
* Called when we receive a "verified" event for the given blockNumber,
* with the computed blockHash.
*/
void blockVerified(long blockNumber, @NonNull Bytes blockHash);

/**
* Called by the Verification Service when we get a verification failure for the given blockNumber.
*/
void blockVerificationFailed(long blockNumber);
}
Loading