diff --git a/.github/workflows/ktlint.yml b/.github/workflows/ktlint.yml index d2721ec..ed798bd 100644 --- a/.github/workflows/ktlint.yml +++ b/.github/workflows/ktlint.yml @@ -17,7 +17,7 @@ jobs: distribution: 'zulu' java-version: '21' - run: | - curl -sSLO https://github.com/pinterest/ktlint/releases/download/1.3.1/ktlint && chmod a+x ktlint && sudo mv ktlint /usr/local/bin/ + curl -sSLO https://github.com/pinterest/ktlint/releases/download/1.5.0/ktlint && chmod a+x ktlint && sudo mv ktlint /usr/local/bin/ - name: run ktlint run: | ktlint --reporter=checkstyle,output=build/ktlint-report.xml diff --git a/build.gradle.kts b/build.gradle.kts index 50ab659..987718f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,7 +19,7 @@ if (!project.hasProperty("isGithubActions")) { } group = "io.newm" -version = "2.3.2-SNAPSHOT" +version = "2.3.3-SNAPSHOT" java.sourceCompatibility = JavaVersion.VERSION_21 java.targetCompatibility = JavaVersion.VERSION_21 diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 9fc33ea..6975955 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -1,17 +1,17 @@ object Versions { const val COMMONS_LOGGING = "1.3.4" const val COMMONS_NUMBERS = "1.2" - const val COROUTINES = "1.8.1" + const val COROUTINES = "1.10.1" const val GOOGLE_TRUTH = "1.4.4" - const val JUNIT = "5.11.0" - const val KOTLIN = "2.0.20" + const val JUNIT = "5.11.4" + const val KOTLIN = "2.1.10" const val KOTLINX_DATETIME = "0.6.1" - const val KOTLINX_SERIALIZATION = "1.7.2" - const val KTLINT = "1.3.1" - const val KTLINT_PLUGIN = "12.1.1" + const val KOTLINX_SERIALIZATION = "1.8.0" + const val KTLINT = "1.5.0" + const val KTLINT_PLUGIN = "12.1.2" const val KTOR = "2.3.12" - const val LOGBACK = "1.5.7" + const val LOGBACK = "1.5.16" const val MAVEN_REPO_AUTH_PLUGIN = "3.0.4" - const val MOCKK = "1.13.12" - const val VERSIONS_PLUGIN = "0.51.0" + const val MOCKK = "1.13.16" + const val VERSIONS_PLUGIN = "0.52.0" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e644113..a4b76b9 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9355b41..e18bc25 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a4..f5feea6 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 7101f8e..9b42019 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/src/main/kotlin/io/newm/kogmios/protocols/model/GovernanceAction.kt b/src/main/kotlin/io/newm/kogmios/protocols/model/GovernanceAction.kt index 6263e85..c115bd4 100644 --- a/src/main/kotlin/io/newm/kogmios/protocols/model/GovernanceAction.kt +++ b/src/main/kotlin/io/newm/kogmios/protocols/model/GovernanceAction.kt @@ -13,13 +13,19 @@ sealed interface GovernanceAction @Serializable @SerialName("protocolParametersUpdate") data class ProtocolParametersUpdateGovernanceAction( + @SerialName("ancestor") + val ancestor: UtxoInput? = null, @SerialName("parameters") val parameters: ProposedProtocolParameters, + @SerialName("guardrails") + val guardrails: GuardrailsHash?, ) : GovernanceAction @Serializable @SerialName("hardForkInitiation") data class HardForkInitiationGovernanceAction( + @SerialName("ancestor") + val ancestor: UtxoInput? = null, @SerialName("version") val version: Version, ) : GovernanceAction @@ -39,12 +45,16 @@ data class TreasuryTransferGovernanceAction( @SerialName("treasuryWithdrawals") data class TreasuryWithdrawalsGovernanceAction( @SerialName("withdrawals") - val rewards: Map, + val withdrawals: Map, + @SerialName("guardrails") + val guardrails: GuardrailsHash?, ) : GovernanceAction @Serializable @SerialName("constitutionalCommittee") data class ConstitutionalCommitteeGovernanceAction( + @SerialName("ancestor") + val ancestor: UtxoInput, @SerialName("members") val members: ConstitutionalCommitteeMembers, @SerialName("quorum") @@ -64,6 +74,8 @@ data class ConstitutionalCommitteeMembers( data class AddedConstitutionalCommitteeMember( @SerialName("id") val id: String, + @SerialName("from") + val from: String, @SerialName("mandate") val mandate: Mandate, ) @@ -77,15 +89,20 @@ data class Mandate( @Serializable @SerialName("constitution") data class ConstitutionGovernanceAction( - @SerialName("hash") - val hash: String, - @SerialName("anchor") - val anchor: AnchorMetadata, + @SerialName("ancestor") + val ancestor: UtxoInput? = null, + @SerialName("guardrails") + val guardrails: GuardrailsHash?, + @SerialName("metadata") + val metadata: AnchorMetadata, ) : GovernanceAction @Serializable @SerialName("noConfidence") -data object NoConfidenceGovernanceAction : GovernanceAction +data class NoConfidenceGovernanceAction( + @SerialName("ancestor") + val ancestor: UtxoInput? = null, +) : GovernanceAction @Serializable @SerialName("information") diff --git a/src/main/kotlin/io/newm/kogmios/protocols/model/GuardrailsHash.kt b/src/main/kotlin/io/newm/kogmios/protocols/model/GuardrailsHash.kt new file mode 100644 index 0000000..34a18e8 --- /dev/null +++ b/src/main/kotlin/io/newm/kogmios/protocols/model/GuardrailsHash.kt @@ -0,0 +1,10 @@ +package io.newm.kogmios.protocols.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class GuardrailsHash( + @SerialName("hash") + val hash: String, +) diff --git a/src/test/kotlin/io/newm/kogmios/protocols/chainsync/ChainSyncTest.kt b/src/test/kotlin/io/newm/kogmios/protocols/chainsync/ChainSyncTest.kt index 9f1ba99..f3fc435 100644 --- a/src/test/kotlin/io/newm/kogmios/protocols/chainsync/ChainSyncTest.kt +++ b/src/test/kotlin/io/newm/kogmios/protocols/chainsync/ChainSyncTest.kt @@ -9,30 +9,34 @@ import io.newm.kogmios.ClientImpl import io.newm.kogmios.createChainSyncClient import io.newm.kogmios.exception.KogmiosException import io.newm.kogmios.protocols.model.BlockPraos -import io.newm.kogmios.protocols.model.result.IntersectionFoundResult -import io.newm.kogmios.protocols.model.fault.IntersectionNotFoundFault import io.newm.kogmios.protocols.model.OriginString import io.newm.kogmios.protocols.model.PointDetail +import io.newm.kogmios.protocols.model.TransactionMetadata +import io.newm.kogmios.protocols.model.fault.IntersectionNotFoundFault +import io.newm.kogmios.protocols.model.result.IntersectionFoundResult import io.newm.kogmios.protocols.model.result.RollBackward import io.newm.kogmios.protocols.model.result.RollForward -import io.newm.kogmios.protocols.model.TransactionMetadata -import kotlinx.coroutines.runBlocking -import kotlinx.serialization.encodeToString -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows -import org.slf4j.LoggerFactory import java.time.Instant import kotlin.math.floor import kotlin.math.max +import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.slf4j.LoggerFactory class ChainSyncTest { companion object { - // local testing + // local testing - preprod private const val TEST_HOST = "localhost" private const val TEST_PORT = 1337 private const val TEST_SECURE = false + // local testing - mainnet +// private const val TEST_HOST = "localhost" +// private const val TEST_PORT = 1338 +// private const val TEST_SECURE = false + // remote testing // private const val TEST_HOST = "ogmios-kogmios-9ab819.us1.demeter.run" // private const val TEST_PORT = 443 @@ -428,24 +432,29 @@ class ChainSyncTest { val intersectResponse = client.findIntersect( listOf( - // preprod - // last byron block - PointDetail( - slot = 84242L, - id = "45899e8002b27df291e09188bfe3aeb5397ac03546a7d0ead93aa2500860f1af", - ), +// // preprod +// // last byron block +// PointDetail( +// slot = 84242L, +// id = "45899e8002b27df291e09188bfe3aeb5397ac03546a7d0ead93aa2500860f1af", +// ), // // last alonzo block // PointDetail( // slot = 3542390L, // id = "f93e682d5b91a94d8660e748aef229c19cb285bfb9830db48941d6a78183d81f" // ) + // plomin hardfork block - mainnet + PointDetail( + slot = 146620747L, + id = "152f9c9e84f00b123f146623cff32faa8b4d7df4284c99322a67574b18074038" + ) ), ) - assertThat(intersectResponse).isNotNull() - assertThat(intersectResponse.result).isInstanceOf(IntersectionFoundResult::class.java) - assertThat((intersectResponse.result.intersection as PointDetail).slot).isEqualTo( - 84242L, - ) +// assertThat(intersectResponse).isNotNull() +// assertThat(intersectResponse.result).isInstanceOf(IntersectionFoundResult::class.java) +// assertThat((intersectResponse.result.intersection as PointDetail).slot).isEqualTo( +// 84242L, +// ) var lastLogged = Instant.EPOCH var isTip = false @@ -480,8 +489,8 @@ class ChainSyncTest { percent, ), ) - val blockJsonString = ClientImpl.json.encodeToString(rollForward.block) - log.info("Block: $blockJsonString") + // val blockJsonString = ClientImpl.json.encodeToString(rollForward.block) + // log.info("Block: $blockJsonString") lastLogged = now } } diff --git a/src/test/kotlin/io/newm/kogmios/protocols/txsubmit/TxSubmitTest.kt b/src/test/kotlin/io/newm/kogmios/protocols/txsubmit/TxSubmitTest.kt index c3ccbfd..a051844 100644 --- a/src/test/kotlin/io/newm/kogmios/protocols/txsubmit/TxSubmitTest.kt +++ b/src/test/kotlin/io/newm/kogmios/protocols/txsubmit/TxSubmitTest.kt @@ -3,7 +3,7 @@ package io.newm.kogmios.protocols.txsubmit import com.google.common.truth.Truth.assertThat import io.newm.kogmios.createTxSubmitClient import io.newm.kogmios.exception.KogmiosException -import io.newm.kogmios.protocols.model.fault.CannotCreateEvaluationContextFaultData +import io.newm.kogmios.protocols.model.fault.ScriptExecutionFailureFaultData import io.newm.kogmios.protocols.model.result.SubmitTxResult import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Disabled @@ -45,10 +45,10 @@ class TxSubmitTest { assertThat( exception.message ).isEqualTo( - "The transaction contains unknown UTxO references as inputs. This can happen if the inputs you're trying to spend have already been spent, or if you've simply referred to non-existing UTxO altogether. The field 'data.unknownOutputReferences' indicates all unknown inputs." + "The transaction is outside of its validity interval. It was either submitted too early or too late. A transaction that has a lower validity bound can only be accepted by the ledger (and make it to the mempool) if the ledger's current slot is greater than the specified bound. The upper bound works similarly, as a time to live. The field 'data.currentSlot' contains the current slot as known of the ledger (this may be different from the current network slot if the ledger is still catching up). The field 'data.validityInterval' is a reminder of the validity interval provided with the transaction." ) assertThat(exception.jsonRpcErrorResponse).isNotNull() - assertThat(exception.jsonRpcErrorResponse.error.code).isEqualTo(3117L) + assertThat(exception.jsonRpcErrorResponse.error.code).isEqualTo(3118L) } } @@ -133,15 +133,13 @@ class TxSubmitTest { ) } assertThat(exception).isNotNull() - assertThat(exception.message).isEqualTo("Unable to create the evaluation context from the given transaction.") + assertThat(exception.message).isEqualTo("Some scripts of the transactions terminated with error(s).") assertThat(exception.jsonRpcErrorResponse).isNotNull() - assertThat(exception.jsonRpcErrorResponse.error.code).isEqualTo(3004L) - assertThat(exception.jsonRpcErrorResponse.error.data).isInstanceOf(CannotCreateEvaluationContextFaultData::class.java) + assertThat(exception.jsonRpcErrorResponse.error.code).isEqualTo(3010L) + assertThat(exception.jsonRpcErrorResponse.error.data).isInstanceOf(ScriptExecutionFailureFaultData::class.java) assertThat( - (exception.jsonRpcErrorResponse.error.data as CannotCreateEvaluationContextFaultData).reason - ).isEqualTo( - "Unknown transaction input (missing from UTxO set): 334958f7971903143be0672aa1818a1d96babe6cddbf445405ba488c8f70d10c#2" - ) + (exception.jsonRpcErrorResponse.error.data as ScriptExecutionFailureFaultData).first().error.code + ).isEqualTo(3110L) } } }