From 09a285b25a110a9448b47d9a8adc328e4517d551 Mon Sep 17 00:00:00 2001 From: DrBlast Date: Tue, 30 Sep 2025 12:20:04 +0300 Subject: [PATCH 1/7] added s --- pom.xml | 24 ++++--- .../CommitToGenerationTransactionInfo.java | 20 ++++++ .../json/deser/TransactionInfoDeser.java | 2 + .../java/node/mock/util/MockHttpRsUtil.java | 4 +- .../CommitToGenerationTxTest.java | 65 +++++++++++++++++++ .../EthereumTransactionFromJsonTest.java | 14 ++-- src/test/resources/stub/addressesD.json | 3 + .../stub/txs/commit_to_generation_tx.json | 20 ++++++ .../eth/eth_invoke_tx_from_block.json | 0 .../{ => txs}/eth/eth_invoke_tx_info.json | 0 .../eth/eth_transfer_tx_from_block.json | 0 .../{ => txs}/eth/eth_transfer_tx_info.json | 0 .../eth/exchange_tx_info_with_eth_sign.json | 0 .../exchange_tx_with_eth_sign_from_block.json | 0 14 files changed, 133 insertions(+), 19 deletions(-) create mode 100644 src/main/java/com/wavesplatform/wavesj/info/CommitToGenerationTransactionInfo.java create mode 100644 src/test/java/node/transactions/CommitToGenerationTxTest.java create mode 100644 src/test/resources/stub/addressesD.json create mode 100644 src/test/resources/stub/txs/commit_to_generation_tx.json rename src/test/resources/stub/{ => txs}/eth/eth_invoke_tx_from_block.json (100%) rename src/test/resources/stub/{ => txs}/eth/eth_invoke_tx_info.json (100%) rename src/test/resources/stub/{ => txs}/eth/eth_transfer_tx_from_block.json (100%) rename src/test/resources/stub/{ => txs}/eth/eth_transfer_tx_info.json (100%) rename src/test/resources/stub/{ => txs}/eth/exchange_tx_info_with_eth_sign.json (100%) rename src/test/resources/stub/{ => txs}/eth/exchange_tx_with_eth_sign_from_block.json (100%) diff --git a/pom.xml b/pom.xml index e300db8..be7de3e 100644 --- a/pom.xml +++ b/pom.xml @@ -81,11 +81,10 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.1 + 3.14.1 - 1.8 - 1.8 - true + 11 + 11 @@ -114,18 +113,23 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.9.1 - - 8 - + 3.5.0 attach-javadocs jar + + 11 + none + + + 11 + none + org.apache.maven.plugins @@ -185,7 +189,7 @@ com.wavesplatform waves-transactions - 1.2.5 + 1.2.6 @@ -220,7 +224,7 @@ org.apache.commons commons-lang3 - 3.14.0 + 3.18.0 diff --git a/src/main/java/com/wavesplatform/wavesj/info/CommitToGenerationTransactionInfo.java b/src/main/java/com/wavesplatform/wavesj/info/CommitToGenerationTransactionInfo.java new file mode 100644 index 0000000..e84ba3e --- /dev/null +++ b/src/main/java/com/wavesplatform/wavesj/info/CommitToGenerationTransactionInfo.java @@ -0,0 +1,20 @@ +package com.wavesplatform.wavesj.info; + +import com.wavesplatform.transactions.CommitToGenerationTransaction; +import com.wavesplatform.transactions.Transaction; +import com.wavesplatform.wavesj.ApplicationStatus; + +public class CommitToGenerationTransactionInfo extends TransactionInfo{ + public CommitToGenerationTransactionInfo(Transaction tx, ApplicationStatus applicationStatus, int height) { + super(tx, applicationStatus, height); + } + + public CommitToGenerationTransaction tx() { + return (CommitToGenerationTransaction) super.tx(); + } + + @Override + public String toString() { + return "CommitToGenerationTransaction{} " + super.toString(); + } +} diff --git a/src/main/java/com/wavesplatform/wavesj/json/deser/TransactionInfoDeser.java b/src/main/java/com/wavesplatform/wavesj/json/deser/TransactionInfoDeser.java index 2a7a673..09aa55f 100644 --- a/src/main/java/com/wavesplatform/wavesj/json/deser/TransactionInfoDeser.java +++ b/src/main/java/com/wavesplatform/wavesj/json/deser/TransactionInfoDeser.java @@ -75,6 +75,8 @@ else if (tx instanceof EthereumTransaction) stateChangesFromJson(codec, json), json.get("bytes").asText() ); + else if (tx instanceof CommitToGenerationTransaction) + return new CommitToGenerationTransactionInfo((CommitToGenerationTransaction) tx, status, height); else throw new IOException("Can't parse transaction info: " + json.toString()); } diff --git a/src/test/java/node/mock/util/MockHttpRsUtil.java b/src/test/java/node/mock/util/MockHttpRsUtil.java index 2c0f5b0..990308b 100644 --- a/src/test/java/node/mock/util/MockHttpRsUtil.java +++ b/src/test/java/node/mock/util/MockHttpRsUtil.java @@ -39,7 +39,7 @@ public static void mockGetBlockRs(Node nodeMock, int height, String rsFilePath) ).thenReturn(createBasicRs(rsFilePath)); } - public static HttpClient mockHttpClient() throws IOException { + public static HttpClient mockHttpClient(String addressFilePath) throws IOException { HttpClient mockHttpClient = Mockito.mock(HttpClient.class); when( mockHttpClient.execute( @@ -47,7 +47,7 @@ public static HttpClient mockHttpClient() throws IOException { rq != null && rq.getURI().toString().endsWith("/addresses") ) ) - ).thenReturn(createBasicRs("src/test/resources/stub/addresses.json")); + ).thenReturn(createBasicRs(addressFilePath)); return mockHttpClient; } diff --git a/src/test/java/node/transactions/CommitToGenerationTxTest.java b/src/test/java/node/transactions/CommitToGenerationTxTest.java new file mode 100644 index 0000000..354b350 --- /dev/null +++ b/src/test/java/node/transactions/CommitToGenerationTxTest.java @@ -0,0 +1,65 @@ +package node.transactions; + +import com.wavesplatform.transactions.CommitToGenerationTransaction; +import com.wavesplatform.transactions.EthereumTransaction; +import com.wavesplatform.transactions.account.PrivateKey; +import com.wavesplatform.transactions.common.Base64String; +import com.wavesplatform.transactions.common.Id; +import com.wavesplatform.wavesj.Node; +import com.wavesplatform.wavesj.Profile; +import com.wavesplatform.wavesj.exceptions.NodeException; +import com.wavesplatform.wavesj.info.CommitToGenerationTransactionInfo; +import com.wavesplatform.wavesj.info.EthereumTransactionInfo; +import org.bouncycastle.util.encoders.Base64; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +import static com.wavesplatform.wavesj.ApplicationStatus.SUCCEEDED; +import static node.mock.util.MockHttpRsUtil.mockHttpClient; +import static node.mock.util.MockHttpRsUtil.mockTransactionInfoRs; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class CommitToGenerationTxTest { + + private final Node node = new Node(Profile.LOCAL, mockHttpClient("src/test/resources/stub/addressesD.json")); + + private static final byte CHAIN_ID = 'D'; + + public CommitToGenerationTxTest() throws NodeException, IOException { + } + + @Test + void readCommitToGenerationTransactionByIdTest() throws NodeException, IOException { + mockTransactionInfoRs(node, + "AFQu6csUmCpXT92RD2hBRMkbPSfi5CGWRwnKJ8ANxsiV", + "src/test/resources/stub/txs/commit_to_generation_tx.json" + ); + + CommitToGenerationTransactionInfo ctgTxInfo = + (CommitToGenerationTransactionInfo) node.getTransactionInfo( + new Id("AFQu6csUmCpXT92RD2hBRMkbPSfi5CGWRwnKJ8ANxsiV") + ); + + CommitToGenerationTransaction ctgTx = ctgTxInfo.tx(); + + assertEquals(20, ctgTx.type()); + assertEquals("AFQu6csUmCpXT92RD2hBRMkbPSfi5CGWRwnKJ8ANxsiV", ctgTx.id().encoded()); + assertEquals(100_00000, ctgTx.fee().value()); + assertEquals(1759169607086L, ctgTx.timestamp()); + assertEquals(1, ctgTx.version()); + assertEquals(CHAIN_ID, ctgTx.chainId()); + assertEquals(80, ctgTx.generationPeriodStart()); + assertEquals("3FSgXpgbT6m1speWgVx3cVxAZKmdr4barHU", ctgTx.sender().address().encoded()); + assertEquals("2JYMTjUK7tC8NQi6TD6oWgy41YbrnXuoLzZydrFKTKt6", ctgTx.sender().encoded()); + assertEquals("6TGkDGP9my3dLeU1LphyCsYDcxeqfiz6xbFdNPG38PdQwEuUZeBTDr8QTTiR3XvMKR", + ctgTx.endorserPublicKey().encoded()); + assertEquals("26DBpJeCPNrvD1q6mhNDcaHHbXg86tcbzfqpswbydjDcPNGSHVmPZozfcPh4z7NpBsz5pvHd9g4p2YqyYFXKpUTZAAHh1cDZbbB25HAE7a57NymCQewnTTQEEC2SCEY4U6qX", + ctgTx.commitmentSignature().encoded()); + assertEquals(73, ctgTxInfo.height()); + assertEquals(SUCCEEDED, ctgTxInfo.applicationStatus()); + System.out.println(new Base64String(ctgTx.bodyBytes())); + System.out.println(new Base64String(ctgTx.toBytes())); + } +} diff --git a/src/test/java/node/transactions/EthereumTransactionFromJsonTest.java b/src/test/java/node/transactions/EthereumTransactionFromJsonTest.java index 11dafed..3dd65b0 100644 --- a/src/test/java/node/transactions/EthereumTransactionFromJsonTest.java +++ b/src/test/java/node/transactions/EthereumTransactionFromJsonTest.java @@ -32,7 +32,7 @@ //todo move bytes attribute to inner transaction public class EthereumTransactionFromJsonTest { - private final Node node = new Node(Profile.LOCAL, mockHttpClient()); + private final Node node = new Node(Profile.LOCAL, mockHttpClient("src/test/resources/stub/addresses.json")); private static final byte PRIVATE_NODE_CHAIN_ID = 'R'; @@ -43,7 +43,7 @@ public EthereumTransactionFromJsonTest() throws NodeException, IOException { void readEthereumTransferTransactionByIdTest() throws NodeException, IOException { mockTransactionInfoRs(node, "Ba4pFx78Ueg3j6CZqjhuBdg5cjxTwTzJJSS6GPpH3Cn4", - "src/test/resources/stub/eth/eth_transfer_tx_info.json" + "src/test/resources/stub/txs/eth/eth_transfer_tx_info.json" ); EthereumTransactionInfo ethTransferTxInfo = @@ -78,7 +78,7 @@ public void readEthereumTransferTransactionFromBlockTest() throws NodeException, mockGetBlockRs( node, 1043438, - "src/test/resources/stub/eth/eth_transfer_tx_from_block.json" + "src/test/resources/stub/txs/eth/eth_transfer_tx_from_block.json" ); Block block = node.getBlock(1043438); @@ -103,7 +103,7 @@ public void readEthereumTransferTransactionFromBlockTest() throws NodeException, void readEthereumInvokeTransactionByIdTest() throws NodeException, IOException { mockTransactionInfoRs(node, "CWuFY42te67sLmc5gwt4NxwHmFjVfJdHkKuLyshTwEct", - "src/test/resources/stub/eth/eth_invoke_tx_info.json" + "src/test/resources/stub/txs/eth/eth_invoke_tx_info.json" ); EthereumTransactionInfo ethInvokeTxInfo = @@ -145,7 +145,7 @@ void readEthereumInvokeTransactionFromBlockTest() throws NodeException, IOExcept mockGetBlockRs( node, 1043725, - "src/test/resources/stub/eth/eth_invoke_tx_from_block.json" + "src/test/resources/stub/txs/eth/eth_invoke_tx_from_block.json" ); Block block = node.getBlock(1043725); @@ -168,7 +168,7 @@ void readEthereumInvokeTransactionFromBlockTest() throws NodeException, IOExcept void readExchangeTransactionInfoWithEthereumSignatureTest() throws IOException, NodeException { mockTransactionInfoRs(node, "3ZPyxs4p7abkj5cf43pUkaHaMPRuBaWC89RX93d2AB6R", - "src/test/resources/stub/eth/exchange_tx_info_with_eth_sign.json" + "src/test/resources/stub/txs/eth/exchange_tx_info_with_eth_sign.json" ); ExchangeTransactionInfo exchangeTxInfo = @@ -248,7 +248,7 @@ void readExchangeTransactionWithEthereumSignatureFormBlockTest() throws IOExcept mockGetBlockRs( node, 1099637, - "src/test/resources/stub/eth/exchange_tx_with_eth_sign_from_block.json" + "src/test/resources/stub/txs/eth/exchange_tx_with_eth_sign_from_block.json" ); ExchangeTransaction exchangeTx = diff --git a/src/test/resources/stub/addressesD.json b/src/test/resources/stub/addressesD.json new file mode 100644 index 0000000..f43a273 --- /dev/null +++ b/src/test/resources/stub/addressesD.json @@ -0,0 +1,3 @@ +[ + "3FSgXpgbT6m1speWgVx3cVxAZKmdr4barHU" +] \ No newline at end of file diff --git a/src/test/resources/stub/txs/commit_to_generation_tx.json b/src/test/resources/stub/txs/commit_to_generation_tx.json new file mode 100644 index 0000000..661a965 --- /dev/null +++ b/src/test/resources/stub/txs/commit_to_generation_tx.json @@ -0,0 +1,20 @@ +{ + "type": 20, + "id": "AFQu6csUmCpXT92RD2hBRMkbPSfi5CGWRwnKJ8ANxsiV", + "fee": 10000000, + "feeAssetId": null, + "timestamp": 1759169607086, + "version": 1, + "chainId": 68, + "sender": "3FSgXpgbT6m1speWgVx3cVxAZKmdr4barHU", + "senderPublicKey": "2JYMTjUK7tC8NQi6TD6oWgy41YbrnXuoLzZydrFKTKt6", + "proofs": [ + "4Ki4PUwpve4tXeDjuNQF7k6jPAfyG9bNBubFGUhfSYWvddCLavdhEGdMmtmrThSLKC2vQATQnQzmz3U1r7wc9Fke" + ], + "endorserPublicKey": "6TGkDGP9my3dLeU1LphyCsYDcxeqfiz6xbFdNPG38PdQwEuUZeBTDr8QTTiR3XvMKR", + "generationPeriodStart": 80, + "commitmentSignature": "26DBpJeCPNrvD1q6mhNDcaHHbXg86tcbzfqpswbydjDcPNGSHVmPZozfcPh4z7NpBsz5pvHd9g4p2YqyYFXKpUTZAAHh1cDZbbB25HAE7a57NymCQewnTTQEEC2SCEY4U6qX", + "height": 73, + "applicationStatus": "succeeded", + "spentComplexity": 0 +} \ No newline at end of file diff --git a/src/test/resources/stub/eth/eth_invoke_tx_from_block.json b/src/test/resources/stub/txs/eth/eth_invoke_tx_from_block.json similarity index 100% rename from src/test/resources/stub/eth/eth_invoke_tx_from_block.json rename to src/test/resources/stub/txs/eth/eth_invoke_tx_from_block.json diff --git a/src/test/resources/stub/eth/eth_invoke_tx_info.json b/src/test/resources/stub/txs/eth/eth_invoke_tx_info.json similarity index 100% rename from src/test/resources/stub/eth/eth_invoke_tx_info.json rename to src/test/resources/stub/txs/eth/eth_invoke_tx_info.json diff --git a/src/test/resources/stub/eth/eth_transfer_tx_from_block.json b/src/test/resources/stub/txs/eth/eth_transfer_tx_from_block.json similarity index 100% rename from src/test/resources/stub/eth/eth_transfer_tx_from_block.json rename to src/test/resources/stub/txs/eth/eth_transfer_tx_from_block.json diff --git a/src/test/resources/stub/eth/eth_transfer_tx_info.json b/src/test/resources/stub/txs/eth/eth_transfer_tx_info.json similarity index 100% rename from src/test/resources/stub/eth/eth_transfer_tx_info.json rename to src/test/resources/stub/txs/eth/eth_transfer_tx_info.json diff --git a/src/test/resources/stub/eth/exchange_tx_info_with_eth_sign.json b/src/test/resources/stub/txs/eth/exchange_tx_info_with_eth_sign.json similarity index 100% rename from src/test/resources/stub/eth/exchange_tx_info_with_eth_sign.json rename to src/test/resources/stub/txs/eth/exchange_tx_info_with_eth_sign.json diff --git a/src/test/resources/stub/eth/exchange_tx_with_eth_sign_from_block.json b/src/test/resources/stub/txs/eth/exchange_tx_with_eth_sign_from_block.json similarity index 100% rename from src/test/resources/stub/eth/exchange_tx_with_eth_sign_from_block.json rename to src/test/resources/stub/txs/eth/exchange_tx_with_eth_sign_from_block.json From 40f8a455581baa70335b126ab85f13f6b726cba9 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Tue, 30 Sep 2025 13:55:21 +0300 Subject: [PATCH 2/7] fixed workflow --- .github/workflows/mvn-publish.yml | 38 ++--- .github/workflows/tests.yml | 29 +--- pom.xml | 135 ++++++++++-------- .../java/base/BaseTestWithNodeInDocker.java | 2 +- 4 files changed, 105 insertions(+), 99 deletions(-) diff --git a/.github/workflows/mvn-publish.yml b/.github/workflows/mvn-publish.yml index 5b2c638..f79cf13 100644 --- a/.github/workflows/mvn-publish.yml +++ b/.github/workflows/mvn-publish.yml @@ -14,37 +14,37 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions/setup-java@v1 + - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 with: - java-version: 1.8 - - uses: actions/cache@v2 - with: - key: ${{ hashFiles('pom.xml') }} - path: ~/.m2/repository - - name: Prepare version - id: maven-version + java-version: 11 + distribution: temurin + check-latest: true + cache: maven + server-id: central + server-username: OSSRH_USERNAME + server-password: OSSRH_PASSWORD + gpg-private-key: ${{ secrets.OSSRH_GPG_KEY }} + - name: Publish artifacts + env: + OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} + OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_PASSPHRASE }} run: | mvn_version=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) git_ref=${GITHUB_REF##*/} pr_number=${{ github.event.number }} if [[ $git_ref =~ v[0-9]+\.[0-9]+\.[0-9]+$ ]] ; then if [[ v$mvn_version != $git_ref ]] ; then - echo Maven version $mvn_version does not match tag $git_ref + echo ::error title=Version mismatch::Maven version $mvn_version does not match tag $git_ref exit 1 fi elif [[ $pr_number != "" && $mvn_version =~ -SNAPSHOT$ ]] ; then pattern="s/(.+)-SNAPSHOT/\1-"$pr_number"-SNAPSHOT/g" mvn_version=$(echo $mvn_version | sed -E $pattern) mvn versions:set -DnewVersion=$mvn_version -DgenerateBackupPoms=false -q -DforceStdout + echo Setting version to $mvn_version elif [[ ! $mvn_version =~ -SNAPSHOT$ ]] ; then - echo Refusing to publish non-snapshot version $mvn_version - echo '::set-output name=skip-publish::true' + echo ::error title=Non-SNAPSHOT version::Refusing to publish non-snapshot version $mvn_version + exit 1 fi - - uses: samuelmeuli/action-maven-publish@v1.4.0 - if: - ${{ steps.maven-version.outputs.skip-publish != 'true' }} - with: - gpg_private_key: ${{ secrets.OSSRH_GPG_KEY_ASCII }} - gpg_passphrase: ${{ secrets.OSSRH_GPG_PASSPHRASE }} - nexus_username: ${{ secrets.OSSRH_USERNAME }} - nexus_password: ${{ secrets.OSSRH_PASSWORD }} + mvn -B deploy diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ef836d0..9f92129 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,31 +10,14 @@ on: jobs: run_tests: - runs-on: ubuntu-latest - steps: - - name: Checkout the repository - uses: actions/checkout@v2 + - uses: actions/checkout@v5 + - uses: actions/setup-java@v5 with: - fetch-depth: 1 - - - name: Set up JDK 8 - uses: actions/setup-java@v1 - with: - java-version: 8 - - - name: Cache Maven packages - uses: actions/cache@v2 - with: - path: ~/.m2 - key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} - restore-keys: ${{ runner.os }}-m2 - - - name: Run tests - run: mvn -B test -Dmaven.test.failure.ignore=true - + java-version: 11 + distribution: temurin + cache: maven + - run: mvn -B test -Dmaven.test.failure.ignore=true - name: Publish test report uses: scacap/action-surefire-report@v1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/pom.xml b/pom.xml index be7de3e..84c807a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.wavesplatform wavesj - 1.6.2 + 1.6.3-SNAPSHOT jar @@ -43,39 +43,56 @@ - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - - gt260 - https://nexus.gt260.com/repository/maven-public/ - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots + central-portal-snapshots + https://central.sonatype.com/repository/maven-snapshots/ + + false + + + true + + + + central + https://central.sonatype.com/repository/maven-snapshots/ + + + - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 + org.apache.maven.plugins + maven-enforcer-plugin + 3.6.1 + + + enforce-maven + + enforce + + + + + 3.6.3 + + + + + + + + org.sonatype.central + central-publishing-maven-plugin + 0.9.0 true - ossrh - https://oss.sonatype.org/ - true + true + published @@ -90,7 +107,7 @@ org.apache.maven.plugins maven-source-plugin - 2.2.1 + 3.3.1 attach-sources @@ -103,17 +120,17 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M3 + 3.5.4 org.jacoco jacoco-maven-plugin - 0.8.7 + 0.8.13 org.apache.maven.plugins maven-javadoc-plugin - 3.5.0 + 3.12.0 attach-javadocs @@ -134,14 +151,7 @@ org.apache.maven.plugins maven-gpg-plugin - 1.6 - - - - --pinentry-mode - loopback - - + 3.2.8 sign-artifacts @@ -152,15 +162,10 @@ - - org.apache.maven.plugins - maven-dependency-plugin - 3.5.0 - org.codehaus.mojo flatten-maven-plugin - 1.2.2 + 1.7.3 ossrh @@ -184,26 +189,44 @@ + + + + com.google.protobuf + protobuf-java + 4.32.1 + + + commons-codec + commons-codec + 1.17.1 + + + org.apache.commons + commons-compress + 1.26.2 + + + com.fasterxml.jackson.core + jackson-core + 2.17.1 + + + + com.wavesplatform waves-transactions - 1.2.6 + 1.2.6-17-SNAPSHOT - com.wavesplatform lang - 1.5.3 - - - - org.scala-lang - scala-library - 2.13.13 + 1.5.11 @@ -217,14 +240,14 @@ ch.qos.logback logback-classic - 1.3.14 + 1.5.18 org.apache.commons commons-lang3 - 3.18.0 + 3.19.0 @@ -243,19 +266,19 @@ org.testcontainers testcontainers - 1.19.6 + 1.21.3 test org.testcontainers junit-jupiter - 1.19.6 + 1.21.3 test org.mockito mockito-core - 4.11.0 + 5.20.0 test diff --git a/src/test/java/base/BaseTestWithNodeInDocker.java b/src/test/java/base/BaseTestWithNodeInDocker.java index e811eec..668dafc 100644 --- a/src/test/java/base/BaseTestWithNodeInDocker.java +++ b/src/test/java/base/BaseTestWithNodeInDocker.java @@ -29,7 +29,7 @@ public abstract class BaseTestWithNodeInDocker { NODE_CONTAINER = null; NODE_API_URL = Profile.LOCAL.uri().toString(); } else { - NODE_CONTAINER = new GenericContainer<>(DockerImageName.parse("wavesplatform/waves-private-node:v1.4.6")) + NODE_CONTAINER = new GenericContainer<>(DockerImageName.parse("wavesplatform/waves-private-node:v1.5.11")) .withExposedPorts(6869) .withStartupTimeout(Duration.of(5, MINUTES)); NODE_CONTAINER.start(); From 16100729dfd07ebdcb7adec8a0c5201f233f20d4 Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Fri, 3 Oct 2025 11:53:56 +0300 Subject: [PATCH 3/7] fixed tests --- .github/workflows/mvn-publish.yml | 46 ++++--------------- pom.xml | 2 +- .../java/com/wavesplatform/wavesj/Node.java | 4 +- src/test/java/node/BlockchainTest.java | 2 +- .../CommitToGenerationTxTest.java | 2 +- .../EthereumTransactionFromJsonTest.java | 20 ++++---- 6 files changed, 25 insertions(+), 51 deletions(-) diff --git a/.github/workflows/mvn-publish.yml b/.github/workflows/mvn-publish.yml index f79cf13..8fbdfb5 100644 --- a/.github/workflows/mvn-publish.yml +++ b/.github/workflows/mvn-publish.yml @@ -11,40 +11,12 @@ on: jobs: publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 - with: - java-version: 11 - distribution: temurin - check-latest: true - cache: maven - server-id: central - server-username: OSSRH_USERNAME - server-password: OSSRH_PASSWORD - gpg-private-key: ${{ secrets.OSSRH_GPG_KEY }} - - name: Publish artifacts - env: - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} - MAVEN_GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_PASSPHRASE }} - run: | - mvn_version=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) - git_ref=${GITHUB_REF##*/} - pr_number=${{ github.event.number }} - if [[ $git_ref =~ v[0-9]+\.[0-9]+\.[0-9]+$ ]] ; then - if [[ v$mvn_version != $git_ref ]] ; then - echo ::error title=Version mismatch::Maven version $mvn_version does not match tag $git_ref - exit 1 - fi - elif [[ $pr_number != "" && $mvn_version =~ -SNAPSHOT$ ]] ; then - pattern="s/(.+)-SNAPSHOT/\1-"$pr_number"-SNAPSHOT/g" - mvn_version=$(echo $mvn_version | sed -E $pattern) - mvn versions:set -DnewVersion=$mvn_version -DgenerateBackupPoms=false -q -DforceStdout - echo Setting version to $mvn_version - elif [[ ! $mvn_version =~ -SNAPSHOT$ ]] ; then - echo ::error title=Non-SNAPSHOT version::Refusing to publish non-snapshot version $mvn_version - exit 1 - fi - mvn -B deploy + uses: wavesplatform/protobuf-schemas/.github/workflows/mvn-publish.yml@5b4331ab892b44ad1fdd71862654421482dcd49c + with: + github-ref-name: ${{ github.ref_name }} + github-event-number: ${{ github.event.number }} + secrets: + OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} + OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + OSSRH_GPG_KEY: ${{ secrets.OSSRH_GPG_KEY }} + OSSRH_GPG_PASSPHRASE: ${{ secrets.OSSRH_GPG_PASSPHRASE }} diff --git a/pom.xml b/pom.xml index 84c807a..1b15567 100644 --- a/pom.xml +++ b/pom.xml @@ -226,7 +226,7 @@ com.wavesplatform lang - 1.5.11 + 1.5.12-SNAPSHOT diff --git a/src/main/java/com/wavesplatform/wavesj/Node.java b/src/main/java/com/wavesplatform/wavesj/Node.java index b2d6fa6..1487df6 100644 --- a/src/main/java/com/wavesplatform/wavesj/Node.java +++ b/src/main/java/com/wavesplatform/wavesj/Node.java @@ -417,7 +417,7 @@ public List getBlocks(int fromHeight, int toHeight) throws IOException, N } public Block getGenesisBlock() throws IOException, NodeException { - return asType(get("/blocks/first"), TypeRef.BLOCK); + return asType(get("/blocks/at/1"), TypeRef.BLOCK); } public Block getLastBlock() throws IOException, NodeException { @@ -750,6 +750,8 @@ public void waitForTransactions(List ids, int waitingInSeconds) throws IOExc return; } catch (Exception e) { lastException = e; + break; + } finally { try { Thread.sleep(pollingIntervalInMillis); } catch (InterruptedException ignored) { diff --git a/src/test/java/node/BlockchainTest.java b/src/test/java/node/BlockchainTest.java index 8efe615..f258fd9 100644 --- a/src/test/java/node/BlockchainTest.java +++ b/src/test/java/node/BlockchainTest.java @@ -26,7 +26,7 @@ void rewards() throws IOException, NodeException { assertThat(rewards.totalWavesAmount()).isGreaterThan(100000000_00000000L); assertThat(rewards.currentReward()).isBetween(5_00000000L, 7_00000000L); assertThat(rewards.minIncrement()).isEqualTo(50000000); - assertThat(rewards.term()).isEqualTo(6); + assertThat(rewards.term()).isEqualTo(3); assertThat(rewards.nextCheck()).isGreaterThan(rewards.votingIntervalStart()); assertThat(rewards.votingInterval()).isEqualTo(3); assertThat(rewards.votingThreshold()).isEqualTo(2); diff --git a/src/test/java/node/transactions/CommitToGenerationTxTest.java b/src/test/java/node/transactions/CommitToGenerationTxTest.java index 354b350..9c7eb64 100644 --- a/src/test/java/node/transactions/CommitToGenerationTxTest.java +++ b/src/test/java/node/transactions/CommitToGenerationTxTest.java @@ -51,7 +51,7 @@ void readCommitToGenerationTransactionByIdTest() throws NodeException, IOExcepti assertEquals(1, ctgTx.version()); assertEquals(CHAIN_ID, ctgTx.chainId()); assertEquals(80, ctgTx.generationPeriodStart()); - assertEquals("3FSgXpgbT6m1speWgVx3cVxAZKmdr4barHU", ctgTx.sender().address().encoded()); + assertEquals("3FSgXpgbT6m1speWgVx3cVxAZKmdr4barHU", ctgTx.sender().address(CHAIN_ID).encoded()); assertEquals("2JYMTjUK7tC8NQi6TD6oWgy41YbrnXuoLzZydrFKTKt6", ctgTx.sender().encoded()); assertEquals("6TGkDGP9my3dLeU1LphyCsYDcxeqfiz6xbFdNPG38PdQwEuUZeBTDr8QTTiR3XvMKR", ctgTx.endorserPublicKey().encoded()); diff --git a/src/test/java/node/transactions/EthereumTransactionFromJsonTest.java b/src/test/java/node/transactions/EthereumTransactionFromJsonTest.java index 3dd65b0..b0dbeb3 100644 --- a/src/test/java/node/transactions/EthereumTransactionFromJsonTest.java +++ b/src/test/java/node/transactions/EthereumTransactionFromJsonTest.java @@ -62,7 +62,7 @@ void readEthereumTransferTransactionByIdTest() throws NodeException, IOException assertEquals(1, ethTransferTx.version()); assertEquals(PRIVATE_NODE_CHAIN_ID, ethTransferTx.chainId()); assertEquals(transferBytes, ethTransferTxInfo.getBytes()); - assertEquals("3M86rqkCp9hYim1cEbRC8MiajcktM16ogVx", ethTransferTx.sender().address().encoded()); + assertEquals("3M86rqkCp9hYim1cEbRC8MiajcktM16ogVx", ethTransferTx.sender().address(PRIVATE_NODE_CHAIN_ID).encoded()); assertEquals("4WcqqW7mkz7AaBgpWQXbewk3wPSHZGqGj38d8HQZe1Umud2HXFswbGhZyoHZWd3thLjz4KW22JM5SB4yyzGiWjNx", ethTransferTx.sender().encoded()); assertEquals(1043438, ethTransferTxInfo.height()); @@ -93,7 +93,7 @@ public void readEthereumTransferTransactionFromBlockTest() throws NodeException, assertEquals(1, ethTransferTx.version()); assertEquals(PRIVATE_NODE_CHAIN_ID, ethTransferTx.chainId()); //bytes - assertEquals("3M86rqkCp9hYim1cEbRC8MiajcktM16ogVx", ethTransferTx.sender().address().encoded()); + assertEquals("3M86rqkCp9hYim1cEbRC8MiajcktM16ogVx", ethTransferTx.sender().address(PRIVATE_NODE_CHAIN_ID).encoded()); assertEquals("4WcqqW7mkz7AaBgpWQXbewk3wPSHZGqGj38d8HQZe1Umud2HXFswbGhZyoHZWd3thLjz4KW22JM5SB4yyzGiWjNx", ethTransferTx.sender().encoded()); // application status @@ -122,7 +122,7 @@ void readEthereumInvokeTransactionByIdTest() throws NodeException, IOException { assertEquals(1, ethInvokeTx.version()); assertEquals(PRIVATE_NODE_CHAIN_ID, ethInvokeTx.chainId()); assertEquals(invokeBytes, ethInvokeTxInfo.getBytes()); - assertEquals("3MCMsdDqmhoz4wFHus4XKD1xJ8SAsimgBTW", ethInvokeTx.sender().address().encoded()); + assertEquals("3MCMsdDqmhoz4wFHus4XKD1xJ8SAsimgBTW", ethInvokeTx.sender().address(PRIVATE_NODE_CHAIN_ID).encoded()); assertEquals("2HAk5dPx7Jx7fwbehqA9JRM9de9E7ZXtxVA2u92vYAp9ttZQiVgChPwBdoJ7ck2wcXmgfGxiAK9a6PPmmtEZmhvd", ethInvokeTx.sender().encoded()); assertEquals(1043725, ethInvokeTxInfo.height()); @@ -159,7 +159,7 @@ void readEthereumInvokeTransactionFromBlockTest() throws NodeException, IOExcept assertEquals(1, ethInvokeTx.version()); assertEquals(PRIVATE_NODE_CHAIN_ID, ethInvokeTx.chainId()); //assertEquals(invokeBytes, ethInvokeTxInfo.getBytes()); - assertEquals("3MCMsdDqmhoz4wFHus4XKD1xJ8SAsimgBTW", ethInvokeTx.sender().address().encoded()); + assertEquals("3MCMsdDqmhoz4wFHus4XKD1xJ8SAsimgBTW", ethInvokeTx.sender().address(PRIVATE_NODE_CHAIN_ID).encoded()); assertEquals("2HAk5dPx7Jx7fwbehqA9JRM9de9E7ZXtxVA2u92vYAp9ttZQiVgChPwBdoJ7ck2wcXmgfGxiAK9a6PPmmtEZmhvd", ethInvokeTx.sender().encoded()); } @@ -185,7 +185,7 @@ void readExchangeTransactionInfoWithEthereumSignatureTest() throws IOException, assertEquals(1652441936773L, exchangeTx.timestamp()); assertEquals(3, exchangeTx.version()); assertEquals(PRIVATE_NODE_CHAIN_ID, exchangeTx.chainId()); - assertEquals("3MNUQ7dgUpRVnY84PJHy33rMPD8v4zm3FDJ", exchangeTx.sender().address().encoded()); + assertEquals("3MNUQ7dgUpRVnY84PJHy33rMPD8v4zm3FDJ", exchangeTx.sender().address(PRIVATE_NODE_CHAIN_ID).encoded()); assertEquals("CsdeJPgJebkW4tsvAaWtfzNvaFd7nWJUGiHrqrtEGN9p", exchangeTx.sender().encoded()); assertEquals("3vbCSYNC6T3BrooeULFpHewphHKLV8p6cDz9NFYQEpkGzA8HCaL7EDTYRYEyNs26AiqS1gdHnxb4H6AYUqdmH8pd", exchangeTx.proofs().get(0).encoded()); @@ -194,7 +194,7 @@ void readExchangeTransactionInfoWithEthereumSignatureTest() throws IOException, assertEquals(4, order1.version()); assertEquals("GozxekHa86f9TqMiibckWKJR8V2FJzYuksBV2ESWVyHF", order1.id().encoded()); - assertEquals("3M6zKVa3cshzkPRRobLaZjzkrT4fHtuSn3Z", order1.sender().address().encoded()); + assertEquals("3M6zKVa3cshzkPRRobLaZjzkrT4fHtuSn3Z", order1.sender().address(PRIVATE_NODE_CHAIN_ID).encoded()); assertEquals("4USoKrfmyQ2xFB8jSjpF95Ma2RFgNDkAbk3td5PhEjrk", order1.sender().encoded()); assertEquals("CsdeJPgJebkW4tsvAaWtfzNvaFd7nWJUGiHrqrtEGN9p", order1.matcher().encoded()); assertEquals("CDyHKz5S5dmnBceTxix1cGQpetXAwWVXKiez2TpvpVLw", order1.assetPair().left().encoded()); @@ -214,7 +214,7 @@ void readExchangeTransactionInfoWithEthereumSignatureTest() throws IOException, Order order2 = exchangeTx.sellOrder(); assertEquals(4, order2.version()); assertEquals("3qnirddnVRKeFR84RPdxDUeFmqcV3SGyQpwgkgEz6SYM", order2.id().encoded()); - assertEquals("3M2jsLHQgaewRmP6BChR2LEjpsef2VZSixf", order2.sender().address().encoded()); + assertEquals("3M2jsLHQgaewRmP6BChR2LEjpsef2VZSixf", order2.sender().address(PRIVATE_NODE_CHAIN_ID).encoded()); assertEquals( "26Djzne1dkfLBMu6nkf4RS9TETmGhMRiaoao1nEkhj5NeqSmwkGXr9WP6zAU4h1rZFSTjgn3EkfTUonZutRNEBSm", order2.sender().encoded() @@ -261,7 +261,7 @@ void readExchangeTransactionWithEthereumSignatureFormBlockTest() throws IOExcept assertEquals(1652441936773L, exchangeTx.timestamp()); assertEquals(3, exchangeTx.version()); assertEquals(PRIVATE_NODE_CHAIN_ID, exchangeTx.chainId()); - assertEquals("3MNUQ7dgUpRVnY84PJHy33rMPD8v4zm3FDJ", exchangeTx.sender().address().encoded()); + assertEquals("3MNUQ7dgUpRVnY84PJHy33rMPD8v4zm3FDJ", exchangeTx.sender().address(PRIVATE_NODE_CHAIN_ID).encoded()); assertEquals("CsdeJPgJebkW4tsvAaWtfzNvaFd7nWJUGiHrqrtEGN9p", exchangeTx.sender().encoded()); assertEquals("3vbCSYNC6T3BrooeULFpHewphHKLV8p6cDz9NFYQEpkGzA8HCaL7EDTYRYEyNs26AiqS1gdHnxb4H6AYUqdmH8pd", exchangeTx.proofs().get(0).encoded()); @@ -270,7 +270,7 @@ void readExchangeTransactionWithEthereumSignatureFormBlockTest() throws IOExcept assertEquals(4, order1.version()); assertEquals("GozxekHa86f9TqMiibckWKJR8V2FJzYuksBV2ESWVyHF", order1.id().encoded()); - assertEquals("3M6zKVa3cshzkPRRobLaZjzkrT4fHtuSn3Z", order1.sender().address().encoded()); + assertEquals("3M6zKVa3cshzkPRRobLaZjzkrT4fHtuSn3Z", order1.sender().address(PRIVATE_NODE_CHAIN_ID).encoded()); assertEquals("4USoKrfmyQ2xFB8jSjpF95Ma2RFgNDkAbk3td5PhEjrk", order1.sender().encoded()); assertEquals("CsdeJPgJebkW4tsvAaWtfzNvaFd7nWJUGiHrqrtEGN9p", order1.matcher().encoded()); assertEquals("CDyHKz5S5dmnBceTxix1cGQpetXAwWVXKiez2TpvpVLw", order1.assetPair().left().encoded()); @@ -290,7 +290,7 @@ void readExchangeTransactionWithEthereumSignatureFormBlockTest() throws IOExcept Order order2 = exchangeTx.sellOrder(); assertEquals(4, order2.version()); assertEquals("3qnirddnVRKeFR84RPdxDUeFmqcV3SGyQpwgkgEz6SYM", order2.id().encoded()); - assertEquals("3M2jsLHQgaewRmP6BChR2LEjpsef2VZSixf", order2.sender().address().encoded()); + assertEquals("3M2jsLHQgaewRmP6BChR2LEjpsef2VZSixf", order2.sender().address(PRIVATE_NODE_CHAIN_ID).encoded()); assertEquals( "26Djzne1dkfLBMu6nkf4RS9TETmGhMRiaoao1nEkhj5NeqSmwkGXr9WP6zAU4h1rZFSTjgn3EkfTUonZutRNEBSm", order2.sender().encoded() From 100886cbcfccbdd9bddc3997341535cc42cdce9e Mon Sep 17 00:00:00 2001 From: DrBlast Date: Tue, 9 Dec 2025 18:36:34 +0300 Subject: [PATCH 4/7] blocks headers structure update --- pom.xml | 30 ++------- .../wavesplatform/wavesj/BlockHeaders.java | 17 ++++- .../wavesj/CommittedGenerator.java | 60 +++++++++++++++++ .../wavesj/ConflictEndorsement.java | 63 ++++++++++++++++++ .../wavesj/FinalizationVoting.java | 64 +++++++++++++++++++ .../java/com/wavesplatform/wavesj/Node.java | 24 +++++++ .../wavesplatform/wavesj/json/TypeRef.java | 2 + .../CommitToGenerationTxTest.java | 38 +++++------ .../stub/txs/commit_to_generation_tx.json | 26 ++++---- 9 files changed, 265 insertions(+), 59 deletions(-) create mode 100644 src/main/java/com/wavesplatform/wavesj/CommittedGenerator.java create mode 100644 src/main/java/com/wavesplatform/wavesj/ConflictEndorsement.java create mode 100644 src/main/java/com/wavesplatform/wavesj/FinalizationVoting.java diff --git a/pom.xml b/pom.xml index 1b15567..688bba1 100644 --- a/pom.xml +++ b/pom.xml @@ -130,38 +130,20 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.12.0 - - - attach-javadocs - - jar - - - 11 - none - - - + 3.3.0 - 11 - none + 8 - - - org.apache.maven.plugins - maven-gpg-plugin - 3.2.8 - sign-artifacts - verify + attach-javadocs - sign + jar + org.codehaus.mojo flatten-maven-plugin @@ -219,7 +201,7 @@ com.wavesplatform waves-transactions - 1.2.6-17-SNAPSHOT + 1.2.6-SNAPSHOT diff --git a/src/main/java/com/wavesplatform/wavesj/BlockHeaders.java b/src/main/java/com/wavesplatform/wavesj/BlockHeaders.java index 877c9f9..e65a220 100644 --- a/src/main/java/com/wavesplatform/wavesj/BlockHeaders.java +++ b/src/main/java/com/wavesplatform/wavesj/BlockHeaders.java @@ -32,6 +32,7 @@ public class BlockHeaders { private final long totalFee; private final long reward; private final Base58String vrf; + private FinalizationVoting finalizationVoting; @JsonCreator public BlockHeaders( @@ -74,6 +75,15 @@ private void nxtConsensus(Map nxtConsensus) { this.generationSignature = new Base58String((String) nxtConsensus.get("generation-signature")); } + @JsonProperty("finalizationVoting") + private void setFinalizationVoting(FinalizationVoting fv) { + this.finalizationVoting = fv; + } + + public FinalizationVoting getFinalizationVoting() { + return finalizationVoting; + } + public int version() { return version; } @@ -163,12 +173,14 @@ public boolean equals(Object o) { Objects.equals(features, that.features) && Objects.equals(generator, that.generator) && Objects.equals(signature, that.signature) && - Objects.equals(vrf, that.vrf); + Objects.equals(vrf, that.vrf) && + Objects.equals(finalizationVoting, that.finalizationVoting); } @Override public int hashCode() { - return Objects.hash(version, timestamp, reference, baseTarget, generationSignature, transactionsRoot, id, features, desiredReward, generator, signature, size, transactionsCount, height, totalFee, reward, vrf); + return Objects.hash(version, timestamp, reference, baseTarget, generationSignature, transactionsRoot, id, features, desiredReward, generator, signature, size, transactionsCount, height, totalFee, reward, vrf, + finalizationVoting); } @Override @@ -191,6 +203,7 @@ public String toString() { ", transactionsCount=" + transactionsCount + ", transactionsRoot='" + transactionsRoot + '\'' + ", size=" + size + + ", finalizationVoting=" + finalizationVoting + '}'; } } diff --git a/src/main/java/com/wavesplatform/wavesj/CommittedGenerator.java b/src/main/java/com/wavesplatform/wavesj/CommittedGenerator.java new file mode 100644 index 0000000..bcf4c2c --- /dev/null +++ b/src/main/java/com/wavesplatform/wavesj/CommittedGenerator.java @@ -0,0 +1,60 @@ +package com.wavesplatform.wavesj; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.wavesplatform.transactions.account.Address; +import com.wavesplatform.transactions.common.Id; + +import java.util.Objects; + +public class CommittedGenerator { + + private final Address address; + private final long balance; + private final Id transactionId; + + @JsonCreator + public CommittedGenerator(@JsonProperty("address") Address address, + @JsonProperty("balance") long balance, + @JsonProperty("transactionId") Id transactionId) { + this.address = address; + this.balance = balance; + this.transactionId = transactionId; + } + + public Address address(){ + return address; + } + + public long balance() { + return balance; + } + + public Id transactionId(){ + return transactionId; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CommittedGenerator that = (CommittedGenerator) o; + return address == that.address && + balance == that.balance && + transactionId == that.transactionId; + } + + @Override + public int hashCode() { + return Objects.hash(address, balance, transactionId); + } + + @Override + public String toString() { + return "CommittedGenerator{" + + "address=" + address.toString() + + ", balance=" + balance + + ", transactionId=" + transactionId + + '}'; + } +} diff --git a/src/main/java/com/wavesplatform/wavesj/ConflictEndorsement.java b/src/main/java/com/wavesplatform/wavesj/ConflictEndorsement.java new file mode 100644 index 0000000..4224249 --- /dev/null +++ b/src/main/java/com/wavesplatform/wavesj/ConflictEndorsement.java @@ -0,0 +1,63 @@ +package com.wavesplatform.wavesj; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.wavesplatform.transactions.account.BlsSignature; +import com.wavesplatform.transactions.common.Base58String; +import com.wavesplatform.transactions.common.Id; + +import java.util.Objects; + +public class ConflictEndorsement { + + private final int endorserIndex; + private final Base58String finalizedBlockId; + private final BlsSignature signature; + + @JsonCreator + public ConflictEndorsement( + @JsonProperty("endorserIndex") int endorserIndex, + @JsonProperty("finalizedBlockId") Id finalizedBlockId, + @JsonProperty("signature") BlsSignature signature + ) { + this.endorserIndex = endorserIndex; + this.finalizedBlockId = finalizedBlockId; + this.signature = signature; + } + + public int getEndorserIndex() { + return endorserIndex; + } + + public Base58String getFinalizedBlockId() { + return finalizedBlockId; + } + + public BlsSignature getSignature() { + return signature; + } + + @Override + public String toString() { + return "ConflictEndorsement{" + + "endorserIndex=" + endorserIndex + + ", finalizedBlockId=" + finalizedBlockId + + ", signature=" + signature + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ConflictEndorsement)) return false; + ConflictEndorsement that = (ConflictEndorsement) o; + return endorserIndex == that.endorserIndex && + Objects.equals(finalizedBlockId, that.finalizedBlockId) && + Objects.equals(signature, that.signature); + } + + @Override + public int hashCode() { + return Objects.hash(endorserIndex, finalizedBlockId, signature); + } +} diff --git a/src/main/java/com/wavesplatform/wavesj/FinalizationVoting.java b/src/main/java/com/wavesplatform/wavesj/FinalizationVoting.java new file mode 100644 index 0000000..aea0da7 --- /dev/null +++ b/src/main/java/com/wavesplatform/wavesj/FinalizationVoting.java @@ -0,0 +1,64 @@ +package com.wavesplatform.wavesj; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.wavesplatform.transactions.account.BlsSignature; +import com.wavesplatform.transactions.common.Base58String; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class FinalizationVoting { + + private final List endorserIndexes; + private final BlsSignature aggregatedEndorsementSignature; + private final List conflictEndorsements; + + @JsonCreator + public FinalizationVoting( + @JsonProperty("endorserIndexes") List endorserIndexes, + @JsonProperty("aggregatedEndorsementSignature") BlsSignature aggregatedEndorsementSignature, + @JsonProperty("conflictEndorsements") List conflictEndorsements + ) { + this.endorserIndexes = endorserIndexes == null ? Collections.emptyList() : endorserIndexes; + this.aggregatedEndorsementSignature = aggregatedEndorsementSignature; + this.conflictEndorsements = conflictEndorsements == null ? Collections.emptyList() : conflictEndorsements; + } + + public List getEndorserIndexes() { + return endorserIndexes; + } + + public BlsSignature getAggregatedEndorsementSignature() { + return aggregatedEndorsementSignature; + } + + public List getConflictEndorsements() { + return conflictEndorsements; + } + + @Override + public String toString() { + return "FinalizationVoting{" + + "endorserIndexes=" + endorserIndexes + + ", aggregatedEndorsementSignature=" + aggregatedEndorsementSignature + + ", conflictEndorsements=" + conflictEndorsements + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FinalizationVoting that = (FinalizationVoting) o; + return Objects.equals(endorserIndexes, that.endorserIndexes) && + Objects.equals(aggregatedEndorsementSignature, that.aggregatedEndorsementSignature) && + Objects.equals(conflictEndorsements, that.conflictEndorsements); + } + + @Override + public int hashCode() { + return Objects.hash(endorserIndexes, aggregatedEndorsementSignature, conflictEndorsements); + } +} diff --git a/src/main/java/com/wavesplatform/wavesj/Node.java b/src/main/java/com/wavesplatform/wavesj/Node.java index 1487df6..120cf91 100644 --- a/src/main/java/com/wavesplatform/wavesj/Node.java +++ b/src/main/java/com/wavesplatform/wavesj/Node.java @@ -44,6 +44,7 @@ import java.util.HashMap; import java.util.List; import java.util.regex.Pattern; +import java.util.stream.IntStream; import static com.wavesplatform.transactions.serializers.json.JsonSerializer.JSON_MAPPER; import static com.wavesplatform.wavesj.Status.CONFIRMED; @@ -390,6 +391,29 @@ public BlockHeaders getLastBlockHeaders() throws IOException, NodeException { return asType(get("/blocks/headers/last"), TypeRef.BLOCK_HEADERS); } + public BlockHeaders getFinalizedBlockHeaders() throws IOException, NodeException { + return asType(get("/blocks/headers/finalized"), TypeRef.BLOCK_HEADERS); + } + + /** + * Returns committed generators at given height. + * + * @param height blockchain height + * @return list of committed generators + * @throws IOException + */ + public List getCommittedGeneratorsAt(int height) throws IOException, NodeException { + return asType(get("/generators/at/" + height), TypeRef.COMMITTED_GENERATORS); + } + + public int getCommittedGeneratorIndex(Address address, int height) throws IOException, NodeException { + List committedGeneratorList = getCommittedGeneratorsAt(height); + return IntStream.range(0, committedGeneratorList.size()) + .filter(i -> committedGeneratorList.get(i).address().equals(address)) + .findFirst() + .orElse(-1); + } + /** * Returns block at given height. * diff --git a/src/main/java/com/wavesplatform/wavesj/json/TypeRef.java b/src/main/java/com/wavesplatform/wavesj/json/TypeRef.java index 0583d2f..05a0694 100644 --- a/src/main/java/com/wavesplatform/wavesj/json/TypeRef.java +++ b/src/main/java/com/wavesplatform/wavesj/json/TypeRef.java @@ -39,6 +39,8 @@ public class TypeRef { public static final TypeReference> BLOCKS = new TypeReference>() {}; + public static final TypeReference> COMMITTED_GENERATORS = new TypeReference>() {}; + public static final TypeReference BLOCK_HEADERS = new TypeReference() {}; public static final TypeReference> BLOCKS_HEADERS = new TypeReference>() {}; diff --git a/src/test/java/node/transactions/CommitToGenerationTxTest.java b/src/test/java/node/transactions/CommitToGenerationTxTest.java index 9c7eb64..2bd88af 100644 --- a/src/test/java/node/transactions/CommitToGenerationTxTest.java +++ b/src/test/java/node/transactions/CommitToGenerationTxTest.java @@ -33,33 +33,33 @@ public CommitToGenerationTxTest() throws NodeException, IOException { @Test void readCommitToGenerationTransactionByIdTest() throws NodeException, IOException { mockTransactionInfoRs(node, - "AFQu6csUmCpXT92RD2hBRMkbPSfi5CGWRwnKJ8ANxsiV", + "EZk7kMzYMDipnRR8WY8ZF2JzLD1fDRMk73jXGWuyipBx", "src/test/resources/stub/txs/commit_to_generation_tx.json" ); CommitToGenerationTransactionInfo ctgTxInfo = (CommitToGenerationTransactionInfo) node.getTransactionInfo( - new Id("AFQu6csUmCpXT92RD2hBRMkbPSfi5CGWRwnKJ8ANxsiV") + new Id("EZk7kMzYMDipnRR8WY8ZF2JzLD1fDRMk73jXGWuyipBx") ); CommitToGenerationTransaction ctgTx = ctgTxInfo.tx(); - assertEquals(20, ctgTx.type()); - assertEquals("AFQu6csUmCpXT92RD2hBRMkbPSfi5CGWRwnKJ8ANxsiV", ctgTx.id().encoded()); - assertEquals(100_00000, ctgTx.fee().value()); - assertEquals(1759169607086L, ctgTx.timestamp()); - assertEquals(1, ctgTx.version()); - assertEquals(CHAIN_ID, ctgTx.chainId()); - assertEquals(80, ctgTx.generationPeriodStart()); - assertEquals("3FSgXpgbT6m1speWgVx3cVxAZKmdr4barHU", ctgTx.sender().address(CHAIN_ID).encoded()); - assertEquals("2JYMTjUK7tC8NQi6TD6oWgy41YbrnXuoLzZydrFKTKt6", ctgTx.sender().encoded()); - assertEquals("6TGkDGP9my3dLeU1LphyCsYDcxeqfiz6xbFdNPG38PdQwEuUZeBTDr8QTTiR3XvMKR", - ctgTx.endorserPublicKey().encoded()); - assertEquals("26DBpJeCPNrvD1q6mhNDcaHHbXg86tcbzfqpswbydjDcPNGSHVmPZozfcPh4z7NpBsz5pvHd9g4p2YqyYFXKpUTZAAHh1cDZbbB25HAE7a57NymCQewnTTQEEC2SCEY4U6qX", - ctgTx.commitmentSignature().encoded()); - assertEquals(73, ctgTxInfo.height()); - assertEquals(SUCCEEDED, ctgTxInfo.applicationStatus()); - System.out.println(new Base64String(ctgTx.bodyBytes())); - System.out.println(new Base64String(ctgTx.toBytes())); +// assertEquals(19, ctgTx.type()); +// assertEquals("EZk7kMzYMDipnRR8WY8ZF2JzLD1fDRMk73jXGWuyipBx", ctgTx.id().encoded()); +// assertEquals(100_00000, ctgTx.fee().value()); +// assertEquals(1760440134127L, ctgTx.timestamp()); +// assertEquals(1, ctgTx.version()); +// assertEquals(CHAIN_ID, ctgTx.chainId()); +// assertEquals(8370, ctgTx.generationPeriodStart()); +// assertEquals("3FZs7eqZSmG56AqfTdWj2wJ1NWTrUZNgS6Q", ctgTx.sender().address(CHAIN_ID).encoded()); +// //assertEquals("2JYMTjUK7tC8NQi6TD6oWgy41YbrnXuoLzZydrFKTKt6", ctgTx.sender().encoded()); +// assertEquals("6TGkDGP9my3dLeU1LphyCsYDcxeqfiz6xbFdNPG38PdQwEuUZeBTDr8QTTiR3XvMKR", +// ctgTx.endorserPublicKey().encoded()); +// assertEquals("26DBpJeCPNrvD1q6mhNDcaHHbXg86tcbzfqpswbydjDcPNGSHVmPZozfcPh4z7NpBsz5pvHd9g4p2YqyYFXKpUTZAAHh1cDZbbB25HAE7a57NymCQewnTTQEEC2SCEY4U6qX", +// ctgTx.commitmentSignature().encoded()); +// assertEquals(73, ctgTxInfo.height()); +// assertEquals(SUCCEEDED, ctgTxInfo.applicationStatus()); +// System.out.println(new Base64String(ctgTx.bodyBytes())); +// System.out.println(new Base64String(ctgTx.toBytes())); } } diff --git a/src/test/resources/stub/txs/commit_to_generation_tx.json b/src/test/resources/stub/txs/commit_to_generation_tx.json index 661a965..5ccb765 100644 --- a/src/test/resources/stub/txs/commit_to_generation_tx.json +++ b/src/test/resources/stub/txs/commit_to_generation_tx.json @@ -1,20 +1,18 @@ { - "type": 20, - "id": "AFQu6csUmCpXT92RD2hBRMkbPSfi5CGWRwnKJ8ANxsiV", - "fee": 10000000, - "feeAssetId": null, - "timestamp": 1759169607086, + "id": "EZk7kMzYMDipnRR8WY8ZF2JzLD1fDRMk73jXGWuyipBx", + "type": 19, "version": 1, "chainId": 68, - "sender": "3FSgXpgbT6m1speWgVx3cVxAZKmdr4barHU", - "senderPublicKey": "2JYMTjUK7tC8NQi6TD6oWgy41YbrnXuoLzZydrFKTKt6", + "senderPublicKey": "BCuRAvrPqngYBKvJ3HKERz3nZZQRKEUMY81FJCEQPfNV", + "sender": "3FZs7eqZSmG56AqfTdWj2wJ1NWTrUZNgS6Q", + "generationPeriodStart": 8370, + "endorserPublicKey": "5vMY4PRQF3XoGgRVosKNhrNwFPyNEK5NhU4bVyer2YY3hQZW4wyBNXME9Gfvqmi1Bw", + "commitmentSignature": "oE5DQBN8RyJKyKQVwa5mwdC6eMCcvUBG6EcpF6TWKkjLuc2UeVRwwtFp2xYoYivx3APPHdzL2hajXRpdUcJ4xXYqTdNpAmwWKoYWSxxUobysd6UxDBqqnHyrA9n3XyMvwNX", + "fee": 10000000, + "feeAssetId": null, + "timestamp": 1760440134127, "proofs": [ - "4Ki4PUwpve4tXeDjuNQF7k6jPAfyG9bNBubFGUhfSYWvddCLavdhEGdMmtmrThSLKC2vQATQnQzmz3U1r7wc9Fke" + "62ZXWcLRZfad9nPKZkuRJQrtV6hLV7wKh69mWBoTgCEoLAnm1ZS1gfZg2UYwKEAcMCXydUVsHcTrzGhCtxuCD4Uo" ], - "endorserPublicKey": "6TGkDGP9my3dLeU1LphyCsYDcxeqfiz6xbFdNPG38PdQwEuUZeBTDr8QTTiR3XvMKR", - "generationPeriodStart": 80, - "commitmentSignature": "26DBpJeCPNrvD1q6mhNDcaHHbXg86tcbzfqpswbydjDcPNGSHVmPZozfcPh4z7NpBsz5pvHd9g4p2YqyYFXKpUTZAAHh1cDZbbB25HAE7a57NymCQewnTTQEEC2SCEY4U6qX", - "height": 73, - "applicationStatus": "succeeded", - "spentComplexity": 0 + "height": 73 } \ No newline at end of file From 306a763148356f73097796391367028834dfcc2e Mon Sep 17 00:00:00 2001 From: DrBlast Date: Thu, 25 Dec 2025 07:06:57 +0300 Subject: [PATCH 5/7] support finalization voting --- pom.xml | 13 +- .../java/com/wavesplatform/wavesj/Block.java | 13 +- .../wavesplatform/wavesj/BlockHeaders.java | 82 +++++++++-- .../wavesj/ChallengedHeader.java | 100 +++++++++++++ .../wavesj/CommittedGenerator.java | 13 +- .../wavesj/ConflictEndorsement.java | 11 +- .../wavesj/FinalizationVoting.java | 16 +- .../java/com/wavesplatform/wavesj/Node.java | 57 +++++--- src/test/java/node/BlockMockTest.java | 138 ++++++++++++++++++ .../java/node/mock/util/MockHttpRsUtil.java | 11 +- .../CommitToGenerationTxTest.java | 42 +++--- .../stub/blocks/block_with_voting.json | 44 ++++++ .../stub/blocks/challenged_block.json | 43 ++++++ .../stub/txs/commit_to_generation_tx.json | 16 +- 14 files changed, 517 insertions(+), 82 deletions(-) create mode 100644 src/main/java/com/wavesplatform/wavesj/ChallengedHeader.java create mode 100644 src/test/java/node/BlockMockTest.java create mode 100644 src/test/resources/stub/blocks/block_with_voting.json create mode 100644 src/test/resources/stub/blocks/challenged_block.json diff --git a/pom.xml b/pom.xml index 688bba1..b5df4c4 100644 --- a/pom.xml +++ b/pom.xml @@ -68,7 +68,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.6.1 + 3.6.2 enforce-maven @@ -100,8 +100,7 @@ maven-compiler-plugin 3.14.1 - 11 - 11 + 11 @@ -176,7 +175,7 @@ com.google.protobuf protobuf-java - 4.32.1 + 4.33.2 commons-codec @@ -201,14 +200,14 @@ com.wavesplatform waves-transactions - 1.2.6-SNAPSHOT + 1.2.6 com.wavesplatform lang - 1.5.12-SNAPSHOT + 1.6.0 @@ -222,7 +221,7 @@ ch.qos.logback logback-classic - 1.5.18 + 1.5.23 diff --git a/src/main/java/com/wavesplatform/wavesj/Block.java b/src/main/java/com/wavesplatform/wavesj/Block.java index 79ad735..b810b6e 100644 --- a/src/main/java/com/wavesplatform/wavesj/Block.java +++ b/src/main/java/com/wavesplatform/wavesj/Block.java @@ -3,10 +3,12 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.wavesplatform.transactions.account.Address; +import com.wavesplatform.transactions.account.PublicKey; import com.wavesplatform.transactions.common.Base58String; import com.wavesplatform.wavesj.info.TransactionWithStatus; import java.util.List; +import java.util.Map; import java.util.Objects; /** @@ -28,6 +30,9 @@ public Block( @JsonProperty("features") List features, @JsonProperty("desiredReward") long desiredReward, @JsonProperty("generator") Address generator, + @JsonProperty("generatorPublicKey") PublicKey generatorPublicKey, + @JsonProperty("stateHash") Base58String stateHash, + @JsonProperty("rewardShares") Map rewardShares, @JsonProperty("signature") Base58String signature, @JsonProperty("blocksize") int size, @JsonProperty("transactionCount") int transactionsCount, @@ -36,9 +41,13 @@ public Block( @JsonProperty("reward") long reward, @JsonProperty("VRF") Base58String vrf, @JsonProperty("fee") long fee, + @JsonProperty("challengedHeader") ChallengedHeader challengedHeader, + @JsonProperty("finalizationVoting") FinalizationVoting finalizationVoting, @JsonProperty("transactions") List transactions) { - super(version, timestamp, reference, transactionsRoot, id, features, desiredReward, generator, - signature, size, transactionsCount, height, totalFee, reward, vrf); + super(version, timestamp, reference, transactionsRoot, id, features, desiredReward, + generator, generatorPublicKey, stateHash, rewardShares, signature, + size, transactionsCount, height, totalFee, reward, vrf, + challengedHeader, finalizationVoting); this.fee = fee; this.transactions = Common.notNull(transactions, "Transactions"); } diff --git a/src/main/java/com/wavesplatform/wavesj/BlockHeaders.java b/src/main/java/com/wavesplatform/wavesj/BlockHeaders.java index e65a220..e43c610 100644 --- a/src/main/java/com/wavesplatform/wavesj/BlockHeaders.java +++ b/src/main/java/com/wavesplatform/wavesj/BlockHeaders.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.wavesplatform.transactions.account.Address; +import com.wavesplatform.transactions.account.PublicKey; import com.wavesplatform.transactions.common.Base58String; import java.util.ArrayList; @@ -25,6 +26,7 @@ public class BlockHeaders { private final List features; private final long desiredReward; private final Address generator; + private final PublicKey generatorPublicKey; private final Base58String signature; private final int size; private final int transactionsCount; @@ -32,7 +34,10 @@ public class BlockHeaders { private final long totalFee; private final long reward; private final Base58String vrf; - private FinalizationVoting finalizationVoting; + private final ChallengedHeader challengedHeader; + private final FinalizationVoting finalizationVoting; + private final Base58String stateHash; + private final Map rewardShares; @JsonCreator public BlockHeaders( @@ -44,18 +49,26 @@ public BlockHeaders( @JsonProperty("features") List features, @JsonProperty("desiredReward") long desiredReward, @JsonProperty("generator") Address generator, + @JsonProperty("generatorPublicKey") PublicKey generatorPublicKey, + @JsonProperty("stateHash") Base58String stateHash, + @JsonProperty("rewardShares") Map rewardShares, @JsonProperty("signature") Base58String signature, @JsonProperty("blocksize") int size, @JsonProperty("transactionCount") int transactionsCount, @JsonProperty("height") int height, @JsonProperty("totalFee") long totalFee, @JsonProperty("reward") long reward, - @JsonProperty("VRF") Base58String vrf) { + @JsonProperty("VRF") Base58String vrf, + @JsonProperty("challengedHeader") ChallengedHeader challengedHeader, + @JsonProperty("finalizationVoting") FinalizationVoting finalizationVoting) { this.height = height; this.version = version; this.timestamp = timestamp; this.reference = Common.notNull(reference, "Reference"); this.generator = Common.notNull(generator, "Generator"); + this.generatorPublicKey = generatorPublicKey; + this.stateHash = stateHash == null ? Base58String.empty() : stateHash; + this.rewardShares = rewardShares == null ? Map.of() : rewardShares; this.signature = Common.notNull(signature, "Signature"); this.id = id == null ? this.signature : id; this.vrf = vrf == null ? Base58String.empty() : vrf; @@ -66,21 +79,22 @@ public BlockHeaders( this.reward = reward; this.desiredReward = desiredReward; this.features = features == null ? new ArrayList<>() : features; + this.challengedHeader = challengedHeader; + this.finalizationVoting = finalizationVoting; } @JsonProperty("nxt-consensus") private void nxtConsensus(Map nxtConsensus) { Object baseTargetObj = nxtConsensus.get("base-target"); - this.baseTarget = baseTargetObj instanceof Long ? (Long) baseTargetObj : (Integer) baseTargetObj; + this.baseTarget = ((Number) nxtConsensus.get("base-target")).longValue(); this.generationSignature = new Base58String((String) nxtConsensus.get("generation-signature")); } - @JsonProperty("finalizationVoting") - private void setFinalizationVoting(FinalizationVoting fv) { - this.finalizationVoting = fv; + public ChallengedHeader challengedHeader() { + return challengedHeader; } - public FinalizationVoting getFinalizationVoting() { + public FinalizationVoting finalizationVoting() { return finalizationVoting; } @@ -124,6 +138,18 @@ public Address generator() { return generator; } + public PublicKey generatorPublicKey() { + return generatorPublicKey; + } + + public Base58String stateHash() { + return stateHash; + } + + public Map rewardShares() { + return rewardShares; + } + public Base58String signature() { return signature; } @@ -172,15 +198,41 @@ public boolean equals(Object o) { Objects.equals(id, that.id) && Objects.equals(features, that.features) && Objects.equals(generator, that.generator) && + Objects.equals(generatorPublicKey, that.generatorPublicKey) && + Objects.equals(stateHash, that.stateHash) && + Objects.equals(rewardShares, that.rewardShares) && Objects.equals(signature, that.signature) && Objects.equals(vrf, that.vrf) && + Objects.equals(challengedHeader, that.challengedHeader) && Objects.equals(finalizationVoting, that.finalizationVoting); } @Override public int hashCode() { - return Objects.hash(version, timestamp, reference, baseTarget, generationSignature, transactionsRoot, id, features, desiredReward, generator, signature, size, transactionsCount, height, totalFee, reward, vrf, - finalizationVoting); + return Objects.hash( + version, + timestamp, + reference, + baseTarget, + generationSignature, + transactionsRoot, + id, + features, + desiredReward, + generator, + generatorPublicKey, + stateHash, + rewardShares, + signature, + size, + transactionsCount, + height, + totalFee, + reward, + vrf, + challengedHeader, + finalizationVoting + ); } @Override @@ -190,20 +242,24 @@ public String toString() { ", height=" + height + ", timestamp=" + timestamp + ", generator=" + generator + + ", generatorPublicKey=" + generatorPublicKey + ", version=" + version + ", reference=" + reference + ", baseTarget=" + baseTarget + - ", generationSignature='" + generationSignature + '\'' + + ", generationSignature=" + generationSignature + + (stateHash != null ? ", stateHash=" + stateHash : "") + ", vrf=" + vrf + ", features=" + features + - ", signature='" + signature + '\'' + + ", signature=" + signature + ", desiredReward=" + desiredReward + ", reward=" + reward + + (rewardShares != null ? ", rewardShares=" + rewardShares : "") + ", totalFee=" + totalFee + ", transactionsCount=" + transactionsCount + - ", transactionsRoot='" + transactionsRoot + '\'' + + ", transactionsRoot=" + transactionsRoot + ", size=" + size + - ", finalizationVoting=" + finalizationVoting + + (challengedHeader != null ? ", challengedHeader=" + challengedHeader : "") + + (finalizationVoting != null ? ", finalizationVoting=" + finalizationVoting : "") + '}'; } } diff --git a/src/main/java/com/wavesplatform/wavesj/ChallengedHeader.java b/src/main/java/com/wavesplatform/wavesj/ChallengedHeader.java new file mode 100644 index 0000000..533367d --- /dev/null +++ b/src/main/java/com/wavesplatform/wavesj/ChallengedHeader.java @@ -0,0 +1,100 @@ +package com.wavesplatform.wavesj; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.wavesplatform.transactions.account.Address; +import com.wavesplatform.transactions.common.Base58String; + +import java.util.List; +import java.util.Objects; + +public class ChallengedHeader { + + private final Base58String headerSignature; + private final List features; + private final Address generator; + private final Base58String generatorPublicKey; + private final long desiredReward; + private final Base58String stateHash; + private final FinalizationVoting finalizationVoting; + + @JsonCreator + public ChallengedHeader( + @JsonProperty("headerSignature") Base58String headerSignature, + @JsonProperty("features") List features, + @JsonProperty("generator") Address generator, + @JsonProperty("generatorPublicKey") Base58String generatorPublicKey, + @JsonProperty("desiredReward") long desiredReward, + @JsonProperty("stateHash") Base58String stateHash, + @JsonProperty("finalizationVoting") FinalizationVoting finalizationVoting + ) { + this.headerSignature = headerSignature; + this.features = features == null ? List.of() : features; + this.generator = generator; + this.generatorPublicKey = generatorPublicKey; + this.desiredReward = desiredReward; + this.stateHash = stateHash; + this.finalizationVoting = finalizationVoting; + } + + public Base58String getHeaderSignature() { + return headerSignature; + } + + public List getFeatures() { + return features; + } + + public Address getGenerator() { + return generator; + } + + public Base58String getGeneratorPublicKey() { + return generatorPublicKey; + } + + public long getDesiredReward() { + return desiredReward; + } + + public Base58String getStateHash() { + return stateHash; + } + + public FinalizationVoting getFinalizationVoting() { + return finalizationVoting; + } + + @Override + public String toString() { + return "ChallengedHeader{" + + "headerSignature=" + headerSignature + + ", features=" + features + + ", generator=" + generator + + ", generatorPublicKey=" + generatorPublicKey + + ", desiredReward=" + desiredReward + + ", stateHash=" + stateHash + + (finalizationVoting != null ? ", finalizationVoting=" + finalizationVoting : "") + + '}'; + + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ChallengedHeader)) return false; + ChallengedHeader that = (ChallengedHeader) o; + return desiredReward == that.desiredReward && + Objects.equals(headerSignature, that.headerSignature) && + Objects.equals(features, that.features) && + Objects.equals(generator, that.generator) && + Objects.equals(generatorPublicKey, that.generatorPublicKey) && + Objects.equals(stateHash, that.stateHash) && + Objects.equals(finalizationVoting, that.finalizationVoting); + } + + @Override + public int hashCode() { + return Objects.hash(headerSignature, features, generator, generatorPublicKey, desiredReward, stateHash, finalizationVoting); + } +} diff --git a/src/main/java/com/wavesplatform/wavesj/CommittedGenerator.java b/src/main/java/com/wavesplatform/wavesj/CommittedGenerator.java index bcf4c2c..95fb772 100644 --- a/src/main/java/com/wavesplatform/wavesj/CommittedGenerator.java +++ b/src/main/java/com/wavesplatform/wavesj/CommittedGenerator.java @@ -12,14 +12,17 @@ public class CommittedGenerator { private final Address address; private final long balance; private final Id transactionId; + private final Integer conflictHeight; @JsonCreator public CommittedGenerator(@JsonProperty("address") Address address, @JsonProperty("balance") long balance, - @JsonProperty("transactionId") Id transactionId) { + @JsonProperty("transactionId") Id transactionId, + @JsonProperty("conflictHeight") Integer conflictHeight) { this.address = address; this.balance = balance; this.transactionId = transactionId; + this.conflictHeight = conflictHeight; } public Address address(){ @@ -34,6 +37,10 @@ public Id transactionId(){ return transactionId; } + public Integer conflictHeight() { + return conflictHeight; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -41,7 +48,8 @@ public boolean equals(Object o) { CommittedGenerator that = (CommittedGenerator) o; return address == that.address && balance == that.balance && - transactionId == that.transactionId; + transactionId == that.transactionId && + Objects.equals(conflictHeight, that.conflictHeight); } @Override @@ -55,6 +63,7 @@ public String toString() { "address=" + address.toString() + ", balance=" + balance + ", transactionId=" + transactionId + + (conflictHeight != null ? ", conflictHeight=" + conflictHeight : "") + '}'; } } diff --git a/src/main/java/com/wavesplatform/wavesj/ConflictEndorsement.java b/src/main/java/com/wavesplatform/wavesj/ConflictEndorsement.java index 4224249..b683daf 100644 --- a/src/main/java/com/wavesplatform/wavesj/ConflictEndorsement.java +++ b/src/main/java/com/wavesplatform/wavesj/ConflictEndorsement.java @@ -13,15 +13,18 @@ public class ConflictEndorsement { private final int endorserIndex; private final Base58String finalizedBlockId; private final BlsSignature signature; + private final int finalizedHeight; @JsonCreator public ConflictEndorsement( @JsonProperty("endorserIndex") int endorserIndex, @JsonProperty("finalizedBlockId") Id finalizedBlockId, + @JsonProperty("finalizedHeight") int finalizedHeight, @JsonProperty("signature") BlsSignature signature ) { this.endorserIndex = endorserIndex; this.finalizedBlockId = finalizedBlockId; + this.finalizedHeight = finalizedHeight; this.signature = signature; } @@ -33,6 +36,10 @@ public Base58String getFinalizedBlockId() { return finalizedBlockId; } + public int getFinalizedHeight() { + return finalizedHeight; + } + public BlsSignature getSignature() { return signature; } @@ -42,6 +49,7 @@ public String toString() { return "ConflictEndorsement{" + "endorserIndex=" + endorserIndex + ", finalizedBlockId=" + finalizedBlockId + + ", finalizedHeight=" + finalizedHeight + ", signature=" + signature + '}'; } @@ -53,11 +61,12 @@ public boolean equals(Object o) { ConflictEndorsement that = (ConflictEndorsement) o; return endorserIndex == that.endorserIndex && Objects.equals(finalizedBlockId, that.finalizedBlockId) && + Objects.equals(finalizedHeight, that.finalizedHeight) && Objects.equals(signature, that.signature); } @Override public int hashCode() { - return Objects.hash(endorserIndex, finalizedBlockId, signature); + return Objects.hash(endorserIndex, finalizedBlockId, finalizedHeight, signature); } } diff --git a/src/main/java/com/wavesplatform/wavesj/FinalizationVoting.java b/src/main/java/com/wavesplatform/wavesj/FinalizationVoting.java index aea0da7..f2ba74f 100644 --- a/src/main/java/com/wavesplatform/wavesj/FinalizationVoting.java +++ b/src/main/java/com/wavesplatform/wavesj/FinalizationVoting.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.wavesplatform.transactions.account.BlsSignature; -import com.wavesplatform.transactions.common.Base58String; import java.util.Collections; import java.util.List; @@ -14,15 +13,18 @@ public class FinalizationVoting { private final List endorserIndexes; private final BlsSignature aggregatedEndorsementSignature; private final List conflictEndorsements; + private final int finalizedHeight; @JsonCreator public FinalizationVoting( @JsonProperty("endorserIndexes") List endorserIndexes, @JsonProperty("aggregatedEndorsementSignature") BlsSignature aggregatedEndorsementSignature, - @JsonProperty("conflictEndorsements") List conflictEndorsements + @JsonProperty("conflictEndorsements") List conflictEndorsements, + @JsonProperty("finalizedHeight") int finalizedHeight ) { this.endorserIndexes = endorserIndexes == null ? Collections.emptyList() : endorserIndexes; this.aggregatedEndorsementSignature = aggregatedEndorsementSignature; + this.finalizedHeight = finalizedHeight; this.conflictEndorsements = conflictEndorsements == null ? Collections.emptyList() : conflictEndorsements; } @@ -34,6 +36,10 @@ public BlsSignature getAggregatedEndorsementSignature() { return aggregatedEndorsementSignature; } + public int getFinalizedHeight() { + return finalizedHeight; + } + public List getConflictEndorsements() { return conflictEndorsements; } @@ -43,7 +49,8 @@ public String toString() { return "FinalizationVoting{" + "endorserIndexes=" + endorserIndexes + ", aggregatedEndorsementSignature=" + aggregatedEndorsementSignature + - ", conflictEndorsements=" + conflictEndorsements + + ", finalizedHeight=" + finalizedHeight + + (!conflictEndorsements.isEmpty() ? ", conflictEndorsements=" + conflictEndorsements : "") + '}'; } @@ -54,11 +61,12 @@ public boolean equals(Object o) { FinalizationVoting that = (FinalizationVoting) o; return Objects.equals(endorserIndexes, that.endorserIndexes) && Objects.equals(aggregatedEndorsementSignature, that.aggregatedEndorsementSignature) && + Objects.equals(finalizedHeight, that.finalizedHeight) && Objects.equals(conflictEndorsements, that.conflictEndorsements); } @Override public int hashCode() { - return Objects.hash(endorserIndexes, aggregatedEndorsementSignature, conflictEndorsements); + return Objects.hash(endorserIndexes, aggregatedEndorsementSignature, finalizedHeight, conflictEndorsements); } } diff --git a/src/main/java/com/wavesplatform/wavesj/Node.java b/src/main/java/com/wavesplatform/wavesj/Node.java index 120cf91..b198757 100644 --- a/src/main/java/com/wavesplatform/wavesj/Node.java +++ b/src/main/java/com/wavesplatform/wavesj/Node.java @@ -365,6 +365,13 @@ public BlockHeaders getBlockHeaders(int height) throws IOException, NodeExceptio return asType(get("/blocks/headers/at/" + height), TypeRef.BLOCK_HEADERS); } + /** + * Returns block header at given height. + * + * @param blockId block id + * @return block object without transactions + * @throws IOException if no block exists at the given height + */ public BlockHeaders getBlockHeaders(Base58String blockId) throws IOException, NodeException { return asType(get("/blocks/headers/" + blockId.toString()), TypeRef.BLOCK_HEADERS); } @@ -382,7 +389,7 @@ public List getBlocksHeaders(int fromHeight, int toHeight) throws } /** - * Returns last block header + * Returns last block headers * * @return block object without transactions * @throws IOException if no block exists at the given height @@ -391,27 +398,14 @@ public BlockHeaders getLastBlockHeaders() throws IOException, NodeException { return asType(get("/blocks/headers/last"), TypeRef.BLOCK_HEADERS); } - public BlockHeaders getFinalizedBlockHeaders() throws IOException, NodeException { - return asType(get("/blocks/headers/finalized"), TypeRef.BLOCK_HEADERS); - } - /** - * Returns committed generators at given height. + * Returns last finalized block headers * - * @param height blockchain height - * @return list of committed generators - * @throws IOException + * @return block object without transactions + * @throws IOException if no block exists at the given height */ - public List getCommittedGeneratorsAt(int height) throws IOException, NodeException { - return asType(get("/generators/at/" + height), TypeRef.COMMITTED_GENERATORS); - } - - public int getCommittedGeneratorIndex(Address address, int height) throws IOException, NodeException { - List committedGeneratorList = getCommittedGeneratorsAt(height); - return IntStream.range(0, committedGeneratorList.size()) - .filter(i -> committedGeneratorList.get(i).address().equals(address)) - .findFirst() - .orElse(-1); + public BlockHeaders getFinalizedBlockHeaders() throws IOException, NodeException { + return asType(get("/blocks/headers/finalized"), TypeRef.BLOCK_HEADERS); } /** @@ -453,6 +447,31 @@ public List getBlocksGeneratedBy(Address generator, int fromHeight, int t "/blocks/address/" + generator.toString() + "/" + fromHeight + "/" + toHeight), TypeRef.BLOCKS); } + /** + * Returns committed generators at given height. + * + * @param height blockchain height + * @return list of committed generators + */ + public List getCommittedGeneratorsAt(int height) throws IOException, NodeException { + return asType(get("/generators/at/" + height), TypeRef.COMMITTED_GENERATORS); + } + + /** + * Returns committed generator index at given height. + * + * @param address address of commited generator + * @param height blockchain height + * @return index of committed generator + */ + public int getCommittedGeneratorIndex(Address address, int height) throws IOException, NodeException { + List committedGeneratorList = getCommittedGeneratorsAt(height); + return IntStream.range(0, committedGeneratorList.size()) + .filter(i -> committedGeneratorList.get(i).address().equals(address)) + .findFirst() + .orElse(-1); + } + //=============== // NODE //=============== diff --git a/src/test/java/node/BlockMockTest.java b/src/test/java/node/BlockMockTest.java new file mode 100644 index 0000000..69d78ba --- /dev/null +++ b/src/test/java/node/BlockMockTest.java @@ -0,0 +1,138 @@ +package node; + +import com.wavesplatform.wavesj.*; +import com.wavesplatform.wavesj.exceptions.NodeException; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.List; + +import static node.mock.util.MockHttpRsUtil.mockGBlockHeadersRs; +import static node.mock.util.MockHttpRsUtil.mockHttpClient; +import static org.junit.jupiter.api.Assertions.*; + +public class BlockMockTest { + private final Node node = new Node(Profile.LOCAL, mockHttpClient("src/test/resources/stub/addressesD.json")); + + private static final byte CHAIN_ID = 'D'; + + public BlockMockTest() throws NodeException, IOException { + } + + @Test + void readBlocksHeadersWithFinalizationVoting() throws NodeException, IOException { + mockGBlockHeadersRs(node, + 16, + "src/test/resources/stub/blocks/block_with_voting.json" + ); + + BlockHeaders bh = node.getBlockHeaders(16); + + // ===== base fields ===== + assertEquals(5, bh.version()); + assertEquals(1766555613090L, bh.timestamp()); + assertEquals("6mb8A1dnf8zdvkuCHbqPi8qukALDm97in9wfiNFcbHNq", bh.reference().encoded()); + assertEquals("AdHHXpTvCPxQw6Ge57BaPpkLKHrVmAy4VBv2UPR3rzBu", bh.transactionsRoot().encoded()); + assertEquals("9xhR5xULkazyC5Po7bPfTHV8APbrH72N2KHfkV4nYDXi", bh.id().encoded()); + + assertEquals(-1, bh.desiredReward()); + assertEquals("3FZs7eqZSmG56AqfTdWj2wJ1NWTrUZNgS6Q", bh.generator().toString()); + + assertEquals( + "67HpHJnrEwJuqvn44JjgHJy5TuRLXfu4kAi1fujVHq8y356JFTmLs1LXJciBpJAbTRV9jkxZYGsUNfzS7G9i5LVN", + bh.signature().encoded() + ); + + assertEquals(1068, bh.size()); + assertEquals(3, bh.transactionsCount()); + assertEquals(16, bh.height()); + assertEquals(300_000L, bh.totalFee()); + assertEquals(6_000_000_000L, bh.reward()); + + assertEquals( + "5VjPUXb4NU9QQFoTsEET2xM9ncJfVzjQYZwpUQENStMH", + bh.vrf().encoded() + ); + + assertEquals(0, bh.features().size()); + assertEquals(20120L, bh.baseTarget()); + assertEquals( + "jUqHiYP7E7LZMS8facqNrjp9m6jLB31TjmCxX3aqubyApK9q6qEBUbqapXi6X38oYjYsW1qBA7rTmAo4GvTC8vSDVRWeLrwfxwsQCgUV7MNyqcMt3efJD6bHuuyUh7yfVie", + bh.generationSignature().encoded() + ); + + FinalizationVoting fv = bh.finalizationVoting(); + assertEquals(14, fv.getFinalizedHeight()); + assertEquals(List.of(1, 3), fv.getEndorserIndexes()); + assertEquals( + "xgHXeGVftVtfxEZhRrfC5Q3pb8DajoGnFed7PxDBC9JegLuW7e1jYjh9QXzU9AeDSB4dShS8id9oThaKwgG4wddevXbiBwenuVFdRXUM3hyqbkcgMCnDLexhZtWhxfrs7AU", + fv.getAggregatedEndorsementSignature().encoded() + ); + + assertEquals(1, fv.getConflictEndorsements().size()); + ConflictEndorsement ce = fv.getConflictEndorsements().get(0); + assertEquals(2, ce.getEndorserIndex()); + assertEquals( + "3LKirJGRvMcdaachGNEuWVSyGbpzWKcagrjsQQuaYXwq", + ce.getFinalizedBlockId().encoded() + ); + assertEquals(13, ce.getFinalizedHeight()); + assertEquals( + "omjkPiJX473jCxnScb5XXwi7MRf8Sb4Wom18X68eFodkMuSv3ztNK8fW3886cSqEDJ9PwWV9goJ4H6EPMSkoZmFNSkfnbZzRwrbrCdYFrjDgWzxw91tyWLtX7F2xKAcHsQq", + ce.getSignature().encoded() + ); + + assertEquals("BCuRAvrPqngYBKvJ3HKERz3nZZQRKEUMY81FJCEQPfNV", + bh.generatorPublicKey().encoded()); + assertEquals("HwLttQ7xwStDavkXbBtfaeUy3QoKJMbCbTkNEezivEL6", + bh.stateHash().encoded()); + assertEquals(3, bh.rewardShares().size()); + } + + @Test + public void readChallengedBlocksHeaders() throws IOException, NodeException { + mockGBlockHeadersRs(node, + 42, + "src/test/resources/stub/blocks/challenged_block.json" + ); + + BlockHeaders bh = node.getBlockHeaders(42); + assertEquals(5, bh.version()); + assertEquals(42, bh.height()); + assertNotNull(bh.generatorPublicKey()); + assertNotNull(bh.stateHash()); + assertNotNull(bh.rewardShares()); + assertEquals(2, bh.rewardShares().size()); + + ChallengedHeader ch = bh.challengedHeader(); + assertNotNull(ch); + assertEquals( + "52SXMJphW45QdshxfYUxH7w6FhXmGXU2zTmW6mDLvcaWVigKjtufQT7gTJ3gimKFx8mwKyGuTtzoMDf6CYWymjLE", + ch.getHeaderSignature().encoded() + ); + + assertNotNull(ch.getFeatures()); + assertTrue(ch.getFeatures().isEmpty()); + assertEquals( + "3Fgtiv5L5q4CXFfwuAfbkjy9ppehkNzjbEG", + ch.getGenerator().encoded() + ); + assertEquals( + "5FUsFwB6b8mE61VMbSB6X7m23NTy4yN8f1fApXo8tZs7", + ch.getGeneratorPublicKey().encoded() + ); + assertEquals(-1L, ch.getDesiredReward()); + assertEquals( + "11111111111111111111111111111111", + ch.getStateHash().encoded() + ); + FinalizationVoting fv = ch.getFinalizationVoting(); + assertNotNull(fv); + assertEquals(List.of(2, 1), fv.getEndorserIndexes()); + assertEquals( + "yEuHinUSJCG8LdNtvtstKp7edVGrwMmGQQ8qf6ghWc8BB9oiJryCMVmsBQrAJQZX7i8cC1d5mqH2jYLJT2QeJ7QSbMGBAWueVcYhUzpoPtwvtG5NxZUcvTsRUjiZEWPT7uD", + fv.getAggregatedEndorsementSignature().encoded() + ); + assertEquals(40, fv.getFinalizedHeight()); + } +} diff --git a/src/test/java/node/mock/util/MockHttpRsUtil.java b/src/test/java/node/mock/util/MockHttpRsUtil.java index 990308b..e5c177a 100644 --- a/src/test/java/node/mock/util/MockHttpRsUtil.java +++ b/src/test/java/node/mock/util/MockHttpRsUtil.java @@ -1,7 +1,6 @@ package node.mock.util; import com.wavesplatform.wavesj.Node; -import com.wavesplatform.wavesj.Profile; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; @@ -39,6 +38,16 @@ public static void mockGetBlockRs(Node nodeMock, int height, String rsFilePath) ).thenReturn(createBasicRs(rsFilePath)); } + public static void mockGBlockHeadersRs(Node nodeMock, int height, String rsFilePath) throws IOException { + when( + nodeMock.client().execute( + argThat(rq -> + rq != null && rq.getURI().equals(nodeMock.uri().resolve("/blocks/headers/at/" + height)) + ) + ) + ).thenReturn(createBasicRs(rsFilePath)); + } + public static HttpClient mockHttpClient(String addressFilePath) throws IOException { HttpClient mockHttpClient = Mockito.mock(HttpClient.class); when( diff --git a/src/test/java/node/transactions/CommitToGenerationTxTest.java b/src/test/java/node/transactions/CommitToGenerationTxTest.java index 2bd88af..41e5487 100644 --- a/src/test/java/node/transactions/CommitToGenerationTxTest.java +++ b/src/test/java/node/transactions/CommitToGenerationTxTest.java @@ -1,16 +1,11 @@ package node.transactions; import com.wavesplatform.transactions.CommitToGenerationTransaction; -import com.wavesplatform.transactions.EthereumTransaction; -import com.wavesplatform.transactions.account.PrivateKey; -import com.wavesplatform.transactions.common.Base64String; import com.wavesplatform.transactions.common.Id; import com.wavesplatform.wavesj.Node; import com.wavesplatform.wavesj.Profile; import com.wavesplatform.wavesj.exceptions.NodeException; import com.wavesplatform.wavesj.info.CommitToGenerationTransactionInfo; -import com.wavesplatform.wavesj.info.EthereumTransactionInfo; -import org.bouncycastle.util.encoders.Base64; import org.junit.jupiter.api.Test; import java.io.IOException; @@ -19,7 +14,6 @@ import static node.mock.util.MockHttpRsUtil.mockHttpClient; import static node.mock.util.MockHttpRsUtil.mockTransactionInfoRs; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; public class CommitToGenerationTxTest { @@ -33,33 +27,31 @@ public CommitToGenerationTxTest() throws NodeException, IOException { @Test void readCommitToGenerationTransactionByIdTest() throws NodeException, IOException { mockTransactionInfoRs(node, - "EZk7kMzYMDipnRR8WY8ZF2JzLD1fDRMk73jXGWuyipBx", + "2r6kpnJbGqNTmLxi9cPuavgxqumGufnisnN8vhuSCpaX", "src/test/resources/stub/txs/commit_to_generation_tx.json" ); CommitToGenerationTransactionInfo ctgTxInfo = (CommitToGenerationTransactionInfo) node.getTransactionInfo( - new Id("EZk7kMzYMDipnRR8WY8ZF2JzLD1fDRMk73jXGWuyipBx") + new Id("2r6kpnJbGqNTmLxi9cPuavgxqumGufnisnN8vhuSCpaX") ); CommitToGenerationTransaction ctgTx = ctgTxInfo.tx(); -// assertEquals(19, ctgTx.type()); -// assertEquals("EZk7kMzYMDipnRR8WY8ZF2JzLD1fDRMk73jXGWuyipBx", ctgTx.id().encoded()); -// assertEquals(100_00000, ctgTx.fee().value()); -// assertEquals(1760440134127L, ctgTx.timestamp()); -// assertEquals(1, ctgTx.version()); -// assertEquals(CHAIN_ID, ctgTx.chainId()); -// assertEquals(8370, ctgTx.generationPeriodStart()); -// assertEquals("3FZs7eqZSmG56AqfTdWj2wJ1NWTrUZNgS6Q", ctgTx.sender().address(CHAIN_ID).encoded()); -// //assertEquals("2JYMTjUK7tC8NQi6TD6oWgy41YbrnXuoLzZydrFKTKt6", ctgTx.sender().encoded()); -// assertEquals("6TGkDGP9my3dLeU1LphyCsYDcxeqfiz6xbFdNPG38PdQwEuUZeBTDr8QTTiR3XvMKR", -// ctgTx.endorserPublicKey().encoded()); -// assertEquals("26DBpJeCPNrvD1q6mhNDcaHHbXg86tcbzfqpswbydjDcPNGSHVmPZozfcPh4z7NpBsz5pvHd9g4p2YqyYFXKpUTZAAHh1cDZbbB25HAE7a57NymCQewnTTQEEC2SCEY4U6qX", -// ctgTx.commitmentSignature().encoded()); -// assertEquals(73, ctgTxInfo.height()); -// assertEquals(SUCCEEDED, ctgTxInfo.applicationStatus()); -// System.out.println(new Base64String(ctgTx.bodyBytes())); -// System.out.println(new Base64String(ctgTx.toBytes())); + assertEquals(19, ctgTx.type()); + assertEquals("2r6kpnJbGqNTmLxi9cPuavgxqumGufnisnN8vhuSCpaX", ctgTx.id().encoded()); + assertEquals(100_00000, ctgTx.fee().value()); + assertEquals(1766488084192L, ctgTx.timestamp()); + assertEquals(1, ctgTx.version()); + assertEquals(CHAIN_ID, ctgTx.chainId()); + assertEquals(2941, ctgTx.generationPeriodStart()); + assertEquals("3FmjX4FAeDXE4ZdDj2JKxzE4QtbxaioXzxM", ctgTx.sender().address(CHAIN_ID).encoded()); + assertEquals("Bn21Eg8HbwZWZQMHXnTFnb64MhVjgH2HygDekQDbjjMq", ctgTx.sender().encoded()); + assertEquals("5t9zL1oqXW6kL3YUAuF8r4rKUaPwohPVrpMWR8Y1bAJtSMipP3TQJYZvpBFB7GWZwo", + ctgTx.endorserPublicKey().encoded()); + assertEquals("u9CTxLENQWyd5egnHrnbnnDKy7mvtrWJfR1AuCL4e4e7uuRTobzxVy1SQBz7ayoY5mRfiTG3PR8niJPT3fdVfsD97EkagBha8ehrLAzdutWSLbiQF2VDwPfi7uvTcp5csMC", + ctgTx.commitmentSignature().encoded()); + assertEquals(73, ctgTxInfo.height()); + assertEquals(SUCCEEDED, ctgTxInfo.applicationStatus()); } } diff --git a/src/test/resources/stub/blocks/block_with_voting.json b/src/test/resources/stub/blocks/block_with_voting.json new file mode 100644 index 0000000..d7a3d56 --- /dev/null +++ b/src/test/resources/stub/blocks/block_with_voting.json @@ -0,0 +1,44 @@ +{ + "version": 5, + "timestamp": 1766555613090, + "reference": "6mb8A1dnf8zdvkuCHbqPi8qukALDm97in9wfiNFcbHNq", + "nxt-consensus": { + "base-target": 20120, + "generation-signature": "jUqHiYP7E7LZMS8facqNrjp9m6jLB31TjmCxX3aqubyApK9q6qEBUbqapXi6X38oYjYsW1qBA7rTmAo4GvTC8vSDVRWeLrwfxwsQCgUV7MNyqcMt3efJD6bHuuyUh7yfVie" + }, + "transactionsRoot": "AdHHXpTvCPxQw6Ge57BaPpkLKHrVmAy4VBv2UPR3rzBu", + "id": "9xhR5xULkazyC5Po7bPfTHV8APbrH72N2KHfkV4nYDXi", + "features": [], + "desiredReward": -1, + "generator": "3FZs7eqZSmG56AqfTdWj2wJ1NWTrUZNgS6Q", + "generatorPublicKey": "BCuRAvrPqngYBKvJ3HKERz3nZZQRKEUMY81FJCEQPfNV", + "stateHash": "HwLttQ7xwStDavkXbBtfaeUy3QoKJMbCbTkNEezivEL6", + "finalizationVoting": { + "endorserIndexes": [ + 1, + 3 + ], + "aggregatedEndorsementSignature": "xgHXeGVftVtfxEZhRrfC5Q3pb8DajoGnFed7PxDBC9JegLuW7e1jYjh9QXzU9AeDSB4dShS8id9oThaKwgG4wddevXbiBwenuVFdRXUM3hyqbkcgMCnDLexhZtWhxfrs7AU", + "finalizedHeight": 14, + "conflictEndorsements": [ + { + "endorserIndex": 2, + "finalizedBlockId": "3LKirJGRvMcdaachGNEuWVSyGbpzWKcagrjsQQuaYXwq", + "finalizedHeight": 13, + "signature": "omjkPiJX473jCxnScb5XXwi7MRf8Sb4Wom18X68eFodkMuSv3ztNK8fW3886cSqEDJ9PwWV9goJ4H6EPMSkoZmFNSkfnbZzRwrbrCdYFrjDgWzxw91tyWLtX7F2xKAcHsQq" + } + ] + }, + "signature": "67HpHJnrEwJuqvn44JjgHJy5TuRLXfu4kAi1fujVHq8y356JFTmLs1LXJciBpJAbTRV9jkxZYGsUNfzS7G9i5LVN", + "blocksize": 1068, + "transactionCount": 3, + "height": 16, + "totalFee": 300000, + "reward": 6000000000, + "rewardShares": { + "3FVGizGxjdi8m4e8WKjbwtzg4rdiiUGkLCu": 2000000000, + "3FZQMZsyypqDUk2r5katP1AUChe7Uzc9dC4": 2000000000, + "3FZs7eqZSmG56AqfTdWj2wJ1NWTrUZNgS6Q": 2000000000 + }, + "VRF": "5VjPUXb4NU9QQFoTsEET2xM9ncJfVzjQYZwpUQENStMH" +} \ No newline at end of file diff --git a/src/test/resources/stub/blocks/challenged_block.json b/src/test/resources/stub/blocks/challenged_block.json new file mode 100644 index 0000000..b7f5e14 --- /dev/null +++ b/src/test/resources/stub/blocks/challenged_block.json @@ -0,0 +1,43 @@ +{ + "version": 5, + "timestamp": 1766556383068, + "reference": "Cgiw4DxerYuir2Eb1J9Efao7MRv6mqNJhhb9DDFT1nyn", + "nxt-consensus": { + "base-target": 20313, + "generation-signature": "zSgfZWVSvDouvPpqn1x4DCaeozoBz9uxorMqmAk9JhgfqpkHa4KRySVfM8WGMnR3qwiQT2DKr7Yym9SeL9YgtLX5u7sa7VTzCtSFABJfLumrYYvberx7BcNtyCx8nUT86m1" + }, + "transactionsRoot": "HUS3QDVUEFXjrDZbUwNoW6zHXvieUfhCRf5fvaGRN3Ft", + "id": "8peDPrKBNC6cXkwXTTXgr18pR9rK8Kr3hmMPuL1M3Y4J", + "features": [], + "desiredReward": -1, + "generator": "3FmGmZaKHxjb2Q1rRc9KXJxirRtPUUQUdPe", + "generatorPublicKey": "BMY9f5tzFwtLPS2VeaKu12sunVo3ydMvXNd8cVNa5cE9", + "stateHash": "E5p1UQAg77FyoYVdt1NKVvczK6w5QNnZKvhN6fbRbs56", + "challengedHeader": { + "headerSignature": "52SXMJphW45QdshxfYUxH7w6FhXmGXU2zTmW6mDLvcaWVigKjtufQT7gTJ3gimKFx8mwKyGuTtzoMDf6CYWymjLE", + "features": [], + "generator": "3Fgtiv5L5q4CXFfwuAfbkjy9ppehkNzjbEG", + "generatorPublicKey": "5FUsFwB6b8mE61VMbSB6X7m23NTy4yN8f1fApXo8tZs7", + "desiredReward": -1, + "stateHash": "11111111111111111111111111111111", + "finalizationVoting": { + "endorserIndexes": [ + 2, + 1 + ], + "aggregatedEndorsementSignature": "yEuHinUSJCG8LdNtvtstKp7edVGrwMmGQQ8qf6ghWc8BB9oiJryCMVmsBQrAJQZX7i8cC1d5mqH2jYLJT2QeJ7QSbMGBAWueVcYhUzpoPtwvtG5NxZUcvTsRUjiZEWPT7uD", + "finalizedHeight": 40 + } + }, + "signature": "3MLuE6nDYH4AZEMsNJuNye3TyYn9rK1VLtzaiaxs73TpHTNqfXATwaq2vY8n2w23TnVYR8FMyRU3QYa1ekLKu1ar", + "blocksize": 981, + "transactionCount": 2, + "height": 42, + "totalFee": 200000, + "reward": 6000000000, + "rewardShares": { + "3FVGizGxjdi8m4e8WKjbwtzg4rdiiUGkLCu": 2000000000, + "3FmGmZaKHxjb2Q1rRc9KXJxirRtPUUQUdPe": 4000000000 + }, + "VRF": "8cVE9ye2suvz5Z6citp8WmAQzifrgmXD7WxUSix8Cqvp" +} \ No newline at end of file diff --git a/src/test/resources/stub/txs/commit_to_generation_tx.json b/src/test/resources/stub/txs/commit_to_generation_tx.json index 5ccb765..d042d9f 100644 --- a/src/test/resources/stub/txs/commit_to_generation_tx.json +++ b/src/test/resources/stub/txs/commit_to_generation_tx.json @@ -1,18 +1,18 @@ { - "id": "EZk7kMzYMDipnRR8WY8ZF2JzLD1fDRMk73jXGWuyipBx", + "id": "2r6kpnJbGqNTmLxi9cPuavgxqumGufnisnN8vhuSCpaX", "type": 19, "version": 1, "chainId": 68, - "senderPublicKey": "BCuRAvrPqngYBKvJ3HKERz3nZZQRKEUMY81FJCEQPfNV", - "sender": "3FZs7eqZSmG56AqfTdWj2wJ1NWTrUZNgS6Q", - "generationPeriodStart": 8370, - "endorserPublicKey": "5vMY4PRQF3XoGgRVosKNhrNwFPyNEK5NhU4bVyer2YY3hQZW4wyBNXME9Gfvqmi1Bw", - "commitmentSignature": "oE5DQBN8RyJKyKQVwa5mwdC6eMCcvUBG6EcpF6TWKkjLuc2UeVRwwtFp2xYoYivx3APPHdzL2hajXRpdUcJ4xXYqTdNpAmwWKoYWSxxUobysd6UxDBqqnHyrA9n3XyMvwNX", + "senderPublicKey": "Bn21Eg8HbwZWZQMHXnTFnb64MhVjgH2HygDekQDbjjMq", + "sender": "3FmjX4FAeDXE4ZdDj2JKxzE4QtbxaioXzxM", + "generationPeriodStart": 2941, + "endorserPublicKey": "5t9zL1oqXW6kL3YUAuF8r4rKUaPwohPVrpMWR8Y1bAJtSMipP3TQJYZvpBFB7GWZwo", + "commitmentSignature": "u9CTxLENQWyd5egnHrnbnnDKy7mvtrWJfR1AuCL4e4e7uuRTobzxVy1SQBz7ayoY5mRfiTG3PR8niJPT3fdVfsD97EkagBha8ehrLAzdutWSLbiQF2VDwPfi7uvTcp5csMC", "fee": 10000000, "feeAssetId": null, - "timestamp": 1760440134127, + "timestamp": 1766488084192, "proofs": [ - "62ZXWcLRZfad9nPKZkuRJQrtV6hLV7wKh69mWBoTgCEoLAnm1ZS1gfZg2UYwKEAcMCXydUVsHcTrzGhCtxuCD4Uo" + "2H7TeCFEBSq6gb325Up2iZPr1jbZk99XugFijYTLbvgH2Ts8NQyCusG5p84FxKySEsVz7RUqsmQQJcCGU3xx75jt" ], "height": 73 } \ No newline at end of file From 9b7aaff8bfb09653044acbe55975a67f54c0a2ce Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Thu, 25 Dec 2025 11:49:17 +0300 Subject: [PATCH 6/7] bumped plugin dependencies --- .github/workflows/mvn-publish.yml | 6 ++- pom.xml | 65 +++++++++++++--------------- src/test/java/util/CompilerTest.java | 52 +++++++++++----------- 3 files changed, 62 insertions(+), 61 deletions(-) diff --git a/.github/workflows/mvn-publish.yml b/.github/workflows/mvn-publish.yml index 8fbdfb5..272489c 100644 --- a/.github/workflows/mvn-publish.yml +++ b/.github/workflows/mvn-publish.yml @@ -9,9 +9,13 @@ on: - v[0-9].[0-9]+.[0-9]+ pull_request: +permissions: + id-token: write + contents: read + jobs: publish: - uses: wavesplatform/protobuf-schemas/.github/workflows/mvn-publish.yml@5b4331ab892b44ad1fdd71862654421482dcd49c + uses: wavesplatform/protobuf-schemas/.github/workflows/mvn-publish.yml@e7cf7fb33a89e52117ac932596a7338f1e23e82b with: github-ref-name: ${{ github.ref_name }} github-event-number: ${{ github.event.number }} diff --git a/pom.xml b/pom.xml index b5df4c4..0974bad 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ - 3.6.3 + 3.9.2 @@ -95,6 +95,20 @@ published + + org.apache.maven.plugins + maven-gpg-plugin + 3.2.8 + + + sign-artifacts + verify + + sign + + + + org.apache.maven.plugins maven-compiler-plugin @@ -106,7 +120,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.1 + 3.4.0 attach-sources @@ -121,17 +135,12 @@ maven-surefire-plugin 3.5.4 - - org.jacoco - jacoco-maven-plugin - 0.8.13 - org.apache.maven.plugins maven-javadoc-plugin - 3.3.0 + 3.12.0 - 8 + 11 @@ -142,27 +151,15 @@ - - org.codehaus.mojo - flatten-maven-plugin - 1.7.3 - - ossrh - + dev.sigstore + sigstore-maven-plugin + 2.0.0 - flatten - process-resources - - flatten - - - - flatten.clean - clean + sign - clean + sign @@ -180,17 +177,17 @@ commons-codec commons-codec - 1.17.1 + 1.20.0 org.apache.commons commons-compress - 1.26.2 + 1.28.0 com.fasterxml.jackson.core jackson-core - 2.17.1 + 2.20.1 @@ -228,14 +225,14 @@ org.apache.commons commons-lang3 - 3.19.0 + 3.20.0 org.junit.jupiter junit-jupiter - 5.10.2 + 5.14.1 test @@ -247,19 +244,19 @@ org.testcontainers testcontainers - 1.21.3 + 2.0.3 test org.testcontainers junit-jupiter - 1.21.3 + 1.21.4 test org.mockito mockito-core - 5.20.0 + 5.21.0 test diff --git a/src/test/java/util/CompilerTest.java b/src/test/java/util/CompilerTest.java index ab578fc..f560251 100644 --- a/src/test/java/util/CompilerTest.java +++ b/src/test/java/util/CompilerTest.java @@ -4,41 +4,41 @@ import com.wavesplatform.wavesj.ScriptInfo; import com.wavesplatform.wavesj.exceptions.CompilationException; import com.wavesplatform.wavesj.util.CompilationUtil; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; public class CompilerTest { @Test public void compileContract() throws CompilationException { ScriptInfo scriptInfo = CompilationUtil.compile(contract); - Assert.assertEquals(new Base64String(compiledContract), scriptInfo.script()); - Assert.assertEquals(207, scriptInfo.complexity()); - Assert.assertEquals(207, scriptInfo.verifierComplexity()); - Assert.assertEquals(Integer.valueOf(21), scriptInfo.callableComplexities().get("issueNft")); - Assert.assertEquals(Integer.valueOf(4), scriptInfo.callableComplexities().get("setPrice")); - Assert.assertEquals(Integer.valueOf(207), scriptInfo.callableComplexities().get("pullTheLever")); - Assert.assertEquals(0L, scriptInfo.extraFee()); + Assertions.assertEquals(new Base64String(compiledContract), scriptInfo.script()); + Assertions.assertEquals(207, scriptInfo.complexity()); + Assertions.assertEquals(207, scriptInfo.verifierComplexity()); + Assertions.assertEquals(Integer.valueOf(21), scriptInfo.callableComplexities().get("issueNft")); + Assertions.assertEquals(Integer.valueOf(4), scriptInfo.callableComplexities().get("setPrice")); + Assertions.assertEquals(Integer.valueOf(207), scriptInfo.callableComplexities().get("pullTheLever")); + Assertions.assertEquals(0L, scriptInfo.extraFee()); } @Test public void compileExpression() throws CompilationException { ScriptInfo scriptInfo = CompilationUtil.compile(expression); - Assert.assertEquals(new Base64String(compiledExpression), scriptInfo.script()); - Assert.assertEquals(3, scriptInfo.complexity()); - Assert.assertEquals(3, scriptInfo.verifierComplexity()); - Assert.assertTrue(scriptInfo.callableComplexities().isEmpty()); - Assert.assertEquals(0L, scriptInfo.extraFee()); + Assertions.assertEquals(new Base64String(compiledExpression), scriptInfo.script()); + Assertions.assertEquals(3, scriptInfo.complexity()); + Assertions.assertEquals(3, scriptInfo.verifierComplexity()); + Assertions.assertTrue(scriptInfo.callableComplexities().isEmpty()); + Assertions.assertEquals(0L, scriptInfo.extraFee()); } @Test public void compileLibrary() throws CompilationException { ScriptInfo scriptInfo = CompilationUtil.compile(library); - Assert.assertEquals(new Base64String(compiledLibrary), scriptInfo.script()); - Assert.assertEquals(0, scriptInfo.complexity()); - Assert.assertEquals(0, scriptInfo.verifierComplexity()); - Assert.assertTrue(scriptInfo.callableComplexities().isEmpty()); - Assert.assertEquals(0L, scriptInfo.extraFee()); + Assertions.assertEquals(new Base64String(compiledLibrary), scriptInfo.script()); + Assertions.assertEquals(0, scriptInfo.complexity()); + Assertions.assertEquals(0, scriptInfo.verifierComplexity()); + Assertions.assertTrue(scriptInfo.callableComplexities().isEmpty()); + Assertions.assertEquals(0L, scriptInfo.extraFee()); } @Test @@ -51,15 +51,15 @@ public void compileV8() throws CompilationException { "let b = [1, 2, 3].replaceByIndex(1, 0)\n" + "a == b[0]"; ScriptInfo scriptInfo = CompilationUtil.compile(script); - Assert.assertEquals(12, scriptInfo.complexity()); - Assert.assertEquals(12, scriptInfo.verifierComplexity()); - Assert.assertTrue(scriptInfo.callableComplexities().isEmpty()); - Assert.assertEquals(0, scriptInfo.extraFee()); + Assertions.assertEquals(12, scriptInfo.complexity()); + Assertions.assertEquals(12, scriptInfo.verifierComplexity()); + Assertions.assertTrue(scriptInfo.callableComplexities().isEmpty()); + Assertions.assertEquals(0, scriptInfo.extraFee()); } - @Test(expected = CompilationException.class) - public void compilationError() throws CompilationException { - CompilationUtil.compile("{-# STDLIB_V 1 #-}"); + @Test + public void compilationError() { + Assertions.assertThrows(CompilationException.class, () -> CompilationUtil.compile("{-# STDLIB_V 1 #-}")); } private static final String contract = "{-# STDLIB_VERSION 6 #-}\n" + From 7a6526917aceece0e8ecde3a0448d9b848398f0b Mon Sep 17 00:00:00 2001 From: Sergey Nazarov Date: Thu, 25 Dec 2025 12:44:57 +0300 Subject: [PATCH 7/7] bumped node image version --- src/test/java/base/BaseTestWithNodeInDocker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/base/BaseTestWithNodeInDocker.java b/src/test/java/base/BaseTestWithNodeInDocker.java index 668dafc..4ba1a91 100644 --- a/src/test/java/base/BaseTestWithNodeInDocker.java +++ b/src/test/java/base/BaseTestWithNodeInDocker.java @@ -29,7 +29,7 @@ public abstract class BaseTestWithNodeInDocker { NODE_CONTAINER = null; NODE_API_URL = Profile.LOCAL.uri().toString(); } else { - NODE_CONTAINER = new GenericContainer<>(DockerImageName.parse("wavesplatform/waves-private-node:v1.5.11")) + NODE_CONTAINER = new GenericContainer<>(DockerImageName.parse("wavesplatform/waves-private-node:v1.6.0")) .withExposedPorts(6869) .withStartupTimeout(Duration.of(5, MINUTES)); NODE_CONTAINER.start();