diff --git a/.gitignore b/.gitignore
index 03a4fb14..6a007e21 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,6 @@ applications/store-build/tmp
/examples/wallet-demo/test-results/
applications/cli/wallet-ui/node_modules/
applications/cli/src/main/resources/static/wallet/
+/applications/cli/chainstate/
+/e2e-tests/evolution-sdk/node_modules/
+/chainstate/
diff --git a/Earthfile b/Earthfile
index c05524d7..16086b72 100644
--- a/Earthfile
+++ b/Earthfile
@@ -5,6 +5,7 @@ ARG --global tag="dev"
ARG --global local="true"
ARG --global REGISTRY_ORG = "bloxbean"
ARG --global build_type="native"
+ARG --global YANO_BRANCH="fix/devkit_fix"
build:
LOCALLY
@@ -22,7 +23,7 @@ cli-docker:
ARG EARTHLY_TARGET_NAME
ARG EARTHLY_GIT_SHORT_HASH
- BUILD ./applications/cli+docker-build --BUILD_TYPE=${build_type} --REGISTRY_ORG=${REGISTRY_ORG} --APP_VERSION=${tag} --COMMIT_ID=${EARTHLY_GIT_SHORT_HASH}
+ BUILD ./applications/cli+docker-build --BUILD_TYPE=${build_type} --REGISTRY_ORG=${REGISTRY_ORG} --APP_VERSION=${tag} --COMMIT_ID=${EARTHLY_GIT_SHORT_HASH} --YANO_BRANCH=${YANO_BRANCH}
viewer:
ARG EARTHLY_TARGET_NAME
@@ -44,6 +45,8 @@ zip:
RUN echo "revision=${EARTHLY_GIT_SHORT_HASH}" >> /app/yaci-devkit-${tag}/config/version
COPY config/env /app/yaci-devkit-${tag}/config/
COPY config/node.properties /app/yaci-devkit-${tag}/config/
+ COPY config/plutus-costmodels-v10.json /app/yaci-devkit-${tag}/config/
+ COPY config/plutus-costmodels-v11.json /app/yaci-devkit-${tag}/config/
COPY bin/devkit.sh /app/yaci-devkit-${tag}/bin/
diff --git a/README.md b/README.md
index 1395002c..80a39903 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-

+

Complete Cardano development environment with instant local devnet
diff --git a/applications/cli/.dockerignore b/applications/cli/.dockerignore
index 0312f06b..a70be4c4 100644
--- a/applications/cli/.dockerignore
+++ b/applications/cli/.dockerignore
@@ -3,4 +3,4 @@ build/libs/yaci-cli-*-plain.jar
yaci-store-*-sources.jar
yaci-store-*-plain.jar
yaci-store-*-javadoc.jar
-
+wallet-ui/node_modules/
diff --git a/applications/cli/Earthfile b/applications/cli/Earthfile
index fc57a66a..c75b7e05 100644
--- a/applications/cli/Earthfile
+++ b/applications/cli/Earthfile
@@ -1,5 +1,14 @@
VERSION 0.8
+wallet-ui-build:
+ FROM node:20-slim
+ WORKDIR /app
+ COPY wallet-ui/package.json wallet-ui/package-lock.json ./
+ RUN npm ci
+ COPY wallet-ui/ ./
+ RUN npx vite build --outDir dist
+ SAVE ARTIFACT dist /wallet
+
cli-java:
ARG EARTHLY_TARGET_NAME
ARG EARTHLY_GIT_SHORT_HASH
@@ -7,6 +16,7 @@ cli-java:
FROM eclipse-temurin:21
COPY . .
+ COPY +wallet-ui-build/wallet src/main/resources/static/wallet
RUN echo git.commit.id.abbrev=${EARTHLY_GIT_SHORT_HASH} > src/main/resources/git.properties
RUN cat src/main/resources/git.properties
@@ -22,6 +32,7 @@ cli-native:
FROM ghcr.io/graalvm/graalvm-community:21
COPY . .
+ COPY +wallet-ui-build/wallet src/main/resources/static/wallet
RUN echo git.commit.id.abbrev=${EARTHLY_GIT_SHORT_HASH} > src/main/resources/git.properties
RUN cat src/main/resources/git.properties
@@ -49,8 +60,9 @@ java-setup:
docker-build:
FROM ubuntu:22.04
ENV JAVA_HOME=/opt/java/openjdk
- ENV STORE_VERSION=0.1.0
- ENV STORE_NATIVE_BRANCH=release/2.0.0-beta3
+ ENV STORE_VERSION=2.0.1-rc1
+ ENV STORE_NATIVE_BRANCH=v2.0.1-rc1
+ ENV YANO_BRANCH=fix/devkit_fix
ARG TARGETOS
ARG TARGETARCH
@@ -58,6 +70,7 @@ docker-build:
ARG APP_VERSION
ARG REGISTRY_ORG
ARG COMMIT_ID
+ ARG YANO_BRANCH
COPY --dir +java-setup/openjdk /opt/java/
ENV PATH="${JAVA_HOME}/bin:${PATH}"
@@ -94,7 +107,9 @@ docker-build:
RUN mkdir -p /app/store/config
COPY docker/store-application.properties /app/store/config/application.properties
- RUN wget https://github.com/bloxbean/yaci-store/releases/download/v${STORE_VERSION}/yaci-store-all-${STORE_VERSION}.jar -O /app/store/yaci-store.jar
+ RUN wget https://github.com/bloxbean/yaci-store/releases/download/v${STORE_VERSION}/yaci-store-${STORE_VERSION}.zip -O /app/store/yaci-store.zip
+ RUN unzip /app/store/yaci-store.zip -d /app/store/
+ RUN cp /app/store/yaci-store-${STORE_VERSION}/yaci-store.jar /app/store/yaci-store.jar
RUN echo ${APP_VERSION} > /app/version
@@ -102,6 +117,13 @@ docker-build:
COPY (../store-build/+store-native/yaci-store* --APP_VERSION=${APP_VERSION} --STORE_BRANCH=${STORE_NATIVE_BRANCH}) /app/store/
END
+ # Yano native binary (always included; Yano is native-only in docker)
+ RUN mkdir -p /app/yano
+ COPY (../yano-build/+yano-native/yano --APP_VERSION=${APP_VERSION} --YANO_BRANCH=${YANO_BRANCH}) /app/yano/yano
+ COPY (../yano-build/+yano-native/config --APP_VERSION=${APP_VERSION} --YANO_BRANCH=${YANO_BRANCH}) /app/yano/config
+ COPY (../yano-build/+yano-native/yano.git.properties --APP_VERSION=${APP_VERSION} --YANO_BRANCH=${YANO_BRANCH}) /app/yano/yano.git.properties
+ RUN chmod +x /app/yano/yano
+
RUN echo "Build type: $BUILD_TYPE"
IF [ "$BUILD_TYPE" = "native" ]
COPY (+cli-native/yaci-cli* --APP_VERSION=${APP_VERSION}) /app/
@@ -116,6 +138,8 @@ docker-build:
RUN mkdir -p /app/config
COPY docker/application.properties /app/config/
+ COPY config/plutus-costmodels-v10.json /app/config/
+ COPY config/plutus-costmodels-v11.json /app/config/
ENV PATH="$PATH:/app/cardano-bin"
ENV CARDANO_NODE_SOCKET_PATH=/clusters/nodes/default/node/node.sock
@@ -128,6 +152,8 @@ docker-build:
EXPOSE 8080
EXPOSE 1337
EXPOSE 1442
+ EXPOSE 6060
+ EXPOSE 14447
ENTRYPOINT ["sh", "/app/yaci-cli.sh"]
diff --git a/applications/cli/build.gradle b/applications/cli/build.gradle
index 511a74e4..a151c284 100644
--- a/applications/cli/build.gradle
+++ b/applications/cli/build.gradle
@@ -34,16 +34,16 @@ dependencies {
implementation 'org.springframework.shell:spring-shell-starter'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.ai:spring-ai-starter-mcp-server-webmvc'
- implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
+ implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.6'
implementation 'org.springframework.boot:spring-boot-starter-logging'
implementation 'org.springframework.boot:spring-boot-starter-mustache'
- implementation('com.bloxbean.cardano:yaci:0.4.0') {
+ implementation('com.bloxbean.cardano:yaci:0.4.3') {
exclude group: 'com.bloxbean.cardano', module: 'cardano-client-core'
}
- implementation 'com.bloxbean.cardano:cardano-client-lib:0.7.1'
- implementation 'com.bloxbean.cardano:cardano-client-backend:0.7.1'
- implementation 'com.bloxbean.cardano:cardano-client-backend-blockfrost:0.7.1'
+ implementation 'com.bloxbean.cardano:cardano-client-lib:0.7.2'
+ implementation 'com.bloxbean.cardano:cardano-client-backend:0.7.2'
+ implementation 'com.bloxbean.cardano:cardano-client-backend-blockfrost:0.7.2'
implementation 'org.apache.commons:commons-compress:1.23.0'
@@ -102,6 +102,7 @@ tasks.register('walletUiInstall', Exec) {
commandLine 'bash', '-c', 'npm install'
inputs.file('wallet-ui/package.json')
outputs.dir('wallet-ui/node_modules')
+ onlyIf { !file('src/main/resources/static/wallet/index.html').exists() }
}
tasks.register('walletUiBuild', Exec) {
@@ -114,6 +115,7 @@ tasks.register('walletUiBuild', Exec) {
inputs.file('wallet-ui/vite.config.ts')
inputs.file('wallet-ui/tailwind.config.cjs')
outputs.dir('src/main/resources/static/wallet')
+ onlyIf { !file('src/main/resources/static/wallet/index.html').exists() }
}
processResources {
@@ -137,7 +139,7 @@ task cliZip(type: Zip) {
from('config') {
into(configDir)
- include '**/*.properties'
+ include '**/*.properties', '**/*.json'
}
include 'yaci-cli*'
diff --git a/applications/cli/config/application.properties b/applications/cli/config/application.properties
index b56712ac..3c7dffb6 100644
--- a/applications/cli/config/application.properties
+++ b/applications/cli/config/application.properties
@@ -7,9 +7,13 @@ server.port=10000
#Default is the user_home/.yaci-cli
#yaci.cli.home=/Users/satya/yacicli
+#Path to directory containing Plutus cost models JSON files (plutus-costmodels-v10.json, plutus-costmodels-v11.json)
+yaci.cli.plutus-costmodels-path=./config
+
ogmios.enabled=false
kupo.enabled=false
yaci.store.enabled=false
+yano.enabled=false
yaci.store.mode=native
@@ -21,6 +25,8 @@ bp.create.enabled=true
#yaci.store.port=8080
#socat.port=3333
#prometheus.port=12798
+#yano.server.port=14447
+#yano.http.port=6060
######################################################
diff --git a/applications/cli/config/download.properties b/applications/cli/config/download.properties
index 63830bd9..01c6ea1d 100644
--- a/applications/cli/config/download.properties
+++ b/applications/cli/config/download.properties
@@ -1,14 +1,18 @@
#Please specify either the version or the full url for the following components
-node.version=10.5.0
-ogmios.version=6.13.0
+node.version=11.0.1
+ogmios.version=6.14.0
kupo.version=2.11.0
-yaci.store.tag=rel-native-2.0.0-beta3
-yaci.store.version=2.0.0-beta3
-yaci.store.jar.version=2.0.0-beta3
+yaci.store.tag=rel-native-2.0.1-rc1
+yaci.store.version=2.0.1-rc1
+yaci.store.jar.version=2.0.1-rc1
+
+yano.tag=v0.1.0-pre3
+yano.version=0.1.0-pre3
#node.url=
#ogmios.url=
#kupo.url=
#yaci.store.url=
#yaci.store.jar.url=
+#yano.url=
diff --git a/applications/cli/config/node.properties b/applications/cli/config/node.properties
index d5a3d7c4..ea6d9a4e 100644
--- a/applications/cli/config/node.properties
+++ b/applications/cli/config/node.properties
@@ -1,3 +1,9 @@
+# Node mode: yano-primary (Yano BP + Haskell relay, supports rollback),
+# companion (Yano bootstraps + Haskell takes over),
+# yano-only (Yano only, fastest startup),
+# haskell-only (legacy, Haskell node only)
+nodeMode=companion
+
#protocolMagic=42
#maxKESEvolutions=60
#securityParam=80
@@ -66,6 +72,8 @@
#dvtTreasuryWithdrawal=0.51f
#committeeMinSize=0
+#ccThresholdNumerator=0
+#ccThresholdDenominator=1
#committeeMaxTermLength=200
#govActionLifetime=10
#govActionDeposit=1000000000
diff --git a/applications/cli/config/plutus-costmodels-v10.json b/applications/cli/config/plutus-costmodels-v10.json
new file mode 100644
index 00000000..f07d0a17
--- /dev/null
+++ b/applications/cli/config/plutus-costmodels-v10.json
@@ -0,0 +1,646 @@
+{
+ "PlutusV1": [
+ 100788,
+ 420,
+ 1,
+ 1,
+ 1000,
+ 173,
+ 0,
+ 1,
+ 1000,
+ 59957,
+ 4,
+ 1,
+ 11183,
+ 32,
+ 201305,
+ 8356,
+ 4,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 100,
+ 100,
+ 16000,
+ 100,
+ 94375,
+ 32,
+ 132994,
+ 32,
+ 61462,
+ 4,
+ 72010,
+ 178,
+ 0,
+ 1,
+ 22151,
+ 32,
+ 91189,
+ 769,
+ 4,
+ 2,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 1000,
+ 42921,
+ 4,
+ 2,
+ 24548,
+ 29498,
+ 38,
+ 1,
+ 898148,
+ 27279,
+ 1,
+ 51775,
+ 558,
+ 1,
+ 39184,
+ 1000,
+ 60594,
+ 1,
+ 141895,
+ 32,
+ 83150,
+ 32,
+ 15299,
+ 32,
+ 76049,
+ 1,
+ 13169,
+ 4,
+ 22100,
+ 10,
+ 28999,
+ 74,
+ 1,
+ 28999,
+ 74,
+ 1,
+ 43285,
+ 552,
+ 1,
+ 44749,
+ 541,
+ 1,
+ 33852,
+ 32,
+ 68246,
+ 32,
+ 72362,
+ 32,
+ 7243,
+ 32,
+ 7391,
+ 32,
+ 11546,
+ 32,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 90434,
+ 519,
+ 0,
+ 1,
+ 74433,
+ 32,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 270652,
+ 22588,
+ 4,
+ 1457325,
+ 64566,
+ 4,
+ 20467,
+ 1,
+ 4,
+ 0,
+ 141992,
+ 32,
+ 100788,
+ 420,
+ 1,
+ 1,
+ 81663,
+ 32,
+ 59498,
+ 32,
+ 20142,
+ 32,
+ 24588,
+ 32,
+ 20744,
+ 32,
+ 25933,
+ 32,
+ 24623,
+ 32,
+ 53384111,
+ 14333,
+ 10
+ ],
+ "PlutusV2": [
+ 100788,
+ 420,
+ 1,
+ 1,
+ 1000,
+ 173,
+ 0,
+ 1,
+ 1000,
+ 59957,
+ 4,
+ 1,
+ 11183,
+ 32,
+ 201305,
+ 8356,
+ 4,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 100,
+ 100,
+ 16000,
+ 100,
+ 94375,
+ 32,
+ 132994,
+ 32,
+ 61462,
+ 4,
+ 72010,
+ 178,
+ 0,
+ 1,
+ 22151,
+ 32,
+ 91189,
+ 769,
+ 4,
+ 2,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 1000,
+ 42921,
+ 4,
+ 2,
+ 24548,
+ 29498,
+ 38,
+ 1,
+ 898148,
+ 27279,
+ 1,
+ 51775,
+ 558,
+ 1,
+ 39184,
+ 1000,
+ 60594,
+ 1,
+ 141895,
+ 32,
+ 83150,
+ 32,
+ 15299,
+ 32,
+ 76049,
+ 1,
+ 13169,
+ 4,
+ 22100,
+ 10,
+ 28999,
+ 74,
+ 1,
+ 28999,
+ 74,
+ 1,
+ 43285,
+ 552,
+ 1,
+ 44749,
+ 541,
+ 1,
+ 33852,
+ 32,
+ 68246,
+ 32,
+ 72362,
+ 32,
+ 7243,
+ 32,
+ 7391,
+ 32,
+ 11546,
+ 32,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 90434,
+ 519,
+ 0,
+ 1,
+ 74433,
+ 32,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 955506,
+ 213312,
+ 0,
+ 2,
+ 270652,
+ 22588,
+ 4,
+ 1457325,
+ 64566,
+ 4,
+ 20467,
+ 1,
+ 4,
+ 0,
+ 141992,
+ 32,
+ 100788,
+ 420,
+ 1,
+ 1,
+ 81663,
+ 32,
+ 59498,
+ 32,
+ 20142,
+ 32,
+ 24588,
+ 32,
+ 20744,
+ 32,
+ 25933,
+ 32,
+ 24623,
+ 32,
+ 43053543,
+ 10,
+ 53384111,
+ 14333,
+ 10,
+ 43574283,
+ 26308,
+ 10
+ ],
+ "PlutusV3": [
+ 100788,
+ 420,
+ 1,
+ 1,
+ 1000,
+ 173,
+ 0,
+ 1,
+ 1000,
+ 59957,
+ 4,
+ 1,
+ 11183,
+ 32,
+ 201305,
+ 8356,
+ 4,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 100,
+ 100,
+ 16000,
+ 100,
+ 94375,
+ 32,
+ 132994,
+ 32,
+ 61462,
+ 4,
+ 72010,
+ 178,
+ 0,
+ 1,
+ 22151,
+ 32,
+ 91189,
+ 769,
+ 4,
+ 2,
+ 85848,
+ 123203,
+ 7305,
+ -900,
+ 1716,
+ 549,
+ 57,
+ 85848,
+ 0,
+ 1,
+ 1,
+ 1000,
+ 42921,
+ 4,
+ 2,
+ 24548,
+ 29498,
+ 38,
+ 1,
+ 898148,
+ 27279,
+ 1,
+ 51775,
+ 558,
+ 1,
+ 39184,
+ 1000,
+ 60594,
+ 1,
+ 141895,
+ 32,
+ 83150,
+ 32,
+ 15299,
+ 32,
+ 76049,
+ 1,
+ 13169,
+ 4,
+ 22100,
+ 10,
+ 28999,
+ 74,
+ 1,
+ 28999,
+ 74,
+ 1,
+ 43285,
+ 552,
+ 1,
+ 44749,
+ 541,
+ 1,
+ 33852,
+ 32,
+ 68246,
+ 32,
+ 72362,
+ 32,
+ 7243,
+ 32,
+ 7391,
+ 32,
+ 11546,
+ 32,
+ 85848,
+ 123203,
+ 7305,
+ -900,
+ 1716,
+ 549,
+ 57,
+ 85848,
+ 0,
+ 1,
+ 90434,
+ 519,
+ 0,
+ 1,
+ 74433,
+ 32,
+ 85848,
+ 123203,
+ 7305,
+ -900,
+ 1716,
+ 549,
+ 57,
+ 85848,
+ 0,
+ 1,
+ 1,
+ 85848,
+ 123203,
+ 7305,
+ -900,
+ 1716,
+ 549,
+ 57,
+ 85848,
+ 0,
+ 1,
+ 955506,
+ 213312,
+ 0,
+ 2,
+ 270652,
+ 22588,
+ 4,
+ 1457325,
+ 64566,
+ 4,
+ 20467,
+ 1,
+ 4,
+ 0,
+ 141992,
+ 32,
+ 100788,
+ 420,
+ 1,
+ 1,
+ 81663,
+ 32,
+ 59498,
+ 32,
+ 20142,
+ 32,
+ 24588,
+ 32,
+ 20744,
+ 32,
+ 25933,
+ 32,
+ 24623,
+ 32,
+ 43053543,
+ 10,
+ 53384111,
+ 14333,
+ 10,
+ 43574283,
+ 26308,
+ 10,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 962335,
+ 18,
+ 2780678,
+ 6,
+ 442008,
+ 1,
+ 52538055,
+ 3756,
+ 18,
+ 267929,
+ 18,
+ 76433006,
+ 8868,
+ 18,
+ 52948122,
+ 18,
+ 1995836,
+ 36,
+ 3227919,
+ 12,
+ 901022,
+ 1,
+ 166917843,
+ 4307,
+ 36,
+ 284546,
+ 36,
+ 158221314,
+ 26549,
+ 36,
+ 74698472,
+ 36,
+ 333849714,
+ 1,
+ 254006273,
+ 72,
+ 2174038,
+ 72,
+ 2261318,
+ 64571,
+ 4,
+ 207616,
+ 8310,
+ 4,
+ 1293828,
+ 28716,
+ 63,
+ 0,
+ 1,
+ 1006041,
+ 43623,
+ 251,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 107878,
+ 680,
+ 0,
+ 1,
+ 95336,
+ 1,
+ 281145,
+ 18848,
+ 0,
+ 1,
+ 180194,
+ 159,
+ 1,
+ 1,
+ 158519,
+ 8942,
+ 0,
+ 1,
+ 159378,
+ 8813,
+ 0,
+ 1,
+ 107490,
+ 3298,
+ 1,
+ 106057,
+ 655,
+ 1,
+ 1964219,
+ 24520,
+ 3
+ ]
+}
diff --git a/applications/cli/config/plutus-costmodels-v11.json b/applications/cli/config/plutus-costmodels-v11.json
new file mode 100644
index 00000000..a3d556d1
--- /dev/null
+++ b/applications/cli/config/plutus-costmodels-v11.json
@@ -0,0 +1,1022 @@
+{
+ "PlutusV1": [
+ 100788,
+ 420,
+ 1,
+ 1,
+ 1000,
+ 173,
+ 0,
+ 1,
+ 1000,
+ 59957,
+ 4,
+ 1,
+ 11183,
+ 32,
+ 201305,
+ 8356,
+ 4,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 100,
+ 100,
+ 16000,
+ 100,
+ 94375,
+ 32,
+ 132994,
+ 32,
+ 61462,
+ 4,
+ 72010,
+ 178,
+ 0,
+ 1,
+ 22151,
+ 32,
+ 91189,
+ 769,
+ 4,
+ 2,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 1000,
+ 42921,
+ 4,
+ 2,
+ 30623,
+ 28755,
+ 75,
+ 1,
+ 898148,
+ 27279,
+ 1,
+ 51775,
+ 558,
+ 1,
+ 39184,
+ 1000,
+ 60594,
+ 1,
+ 141895,
+ 32,
+ 83150,
+ 32,
+ 15299,
+ 32,
+ 76049,
+ 1,
+ 13169,
+ 4,
+ 22100,
+ 10,
+ 28999,
+ 74,
+ 1,
+ 28999,
+ 74,
+ 1,
+ 43285,
+ 552,
+ 1,
+ 44749,
+ 541,
+ 1,
+ 33852,
+ 32,
+ 68246,
+ 32,
+ 72362,
+ 32,
+ 7243,
+ 32,
+ 7391,
+ 32,
+ 11546,
+ 32,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 90434,
+ 519,
+ 0,
+ 1,
+ 74433,
+ 32,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 270652,
+ 22588,
+ 4,
+ 1457325,
+ 64566,
+ 4,
+ 20467,
+ 1,
+ 4,
+ 0,
+ 141992,
+ 32,
+ 100788,
+ 420,
+ 1,
+ 1,
+ 81663,
+ 32,
+ 59498,
+ 32,
+ 20142,
+ 32,
+ 24588,
+ 32,
+ 20744,
+ 32,
+ 25933,
+ 32,
+ 24623,
+ 32,
+ 53384111,
+ 14333,
+ 10,
+ 955506,
+ 213312,
+ 0,
+ 2,
+ 43053543,
+ 10,
+ 43574283,
+ 26308,
+ 10,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 962335,
+ 18,
+ 2780678,
+ 6,
+ 442008,
+ 1,
+ 52538055,
+ 3756,
+ 18,
+ 267929,
+ 18,
+ 76433006,
+ 8868,
+ 18,
+ 52948122,
+ 18,
+ 1995836,
+ 36,
+ 3227919,
+ 12,
+ 901022,
+ 1,
+ 166917843,
+ 4307,
+ 36,
+ 284546,
+ 36,
+ 158221314,
+ 26549,
+ 36,
+ 74698472,
+ 36,
+ 333849714,
+ 1,
+ 254006273,
+ 72,
+ 2174038,
+ 72,
+ 2261318,
+ 64571,
+ 4,
+ 207616,
+ 8310,
+ 4,
+ 1293828,
+ 28716,
+ 63,
+ 0,
+ 1,
+ 1006041,
+ 43623,
+ 251,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 107878,
+ 680,
+ 0,
+ 1,
+ 95336,
+ 1,
+ 281145,
+ 18848,
+ 0,
+ 1,
+ 180194,
+ 159,
+ 1,
+ 1,
+ 158519,
+ 8942,
+ 0,
+ 1,
+ 159378,
+ 8813,
+ 0,
+ 1,
+ 107490,
+ 3298,
+ 1,
+ 106057,
+ 655,
+ 1,
+ 1964219,
+ 24520,
+ 3,
+ 607153,
+ 231697,
+ 53144,
+ 0,
+ 1,
+ 116711,
+ 1957,
+ 4,
+ 231883,
+ 10,
+ 1000,
+ 24838,
+ 7,
+ 1,
+ 232010,
+ 32,
+ 321837444,
+ 25087669,
+ 18,
+ 617887431,
+ 67302824,
+ 36,
+ 356924,
+ 18413,
+ 45,
+ 21,
+ 219951,
+ 9444,
+ 1,
+ 1000,
+ 172116,
+ 183150,
+ 6,
+ 24,
+ 21,
+ 213283,
+ 618401,
+ 1998,
+ 28258,
+ 1,
+ 1000,
+ 38159,
+ 2,
+ 22,
+ 1000,
+ 95933,
+ 1,
+ 1,
+ 11,
+ 1000,
+ 277577,
+ 12,
+ 21
+ ],
+ "PlutusV2": [
+ 100788,
+ 420,
+ 1,
+ 1,
+ 1000,
+ 173,
+ 0,
+ 1,
+ 1000,
+ 59957,
+ 4,
+ 1,
+ 11183,
+ 32,
+ 201305,
+ 8356,
+ 4,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 100,
+ 100,
+ 16000,
+ 100,
+ 94375,
+ 32,
+ 132994,
+ 32,
+ 61462,
+ 4,
+ 72010,
+ 178,
+ 0,
+ 1,
+ 22151,
+ 32,
+ 91189,
+ 769,
+ 4,
+ 2,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 1000,
+ 42921,
+ 4,
+ 2,
+ 30623,
+ 28755,
+ 75,
+ 1,
+ 898148,
+ 27279,
+ 1,
+ 51775,
+ 558,
+ 1,
+ 39184,
+ 1000,
+ 60594,
+ 1,
+ 141895,
+ 32,
+ 83150,
+ 32,
+ 15299,
+ 32,
+ 76049,
+ 1,
+ 13169,
+ 4,
+ 22100,
+ 10,
+ 28999,
+ 74,
+ 1,
+ 28999,
+ 74,
+ 1,
+ 43285,
+ 552,
+ 1,
+ 44749,
+ 541,
+ 1,
+ 33852,
+ 32,
+ 68246,
+ 32,
+ 72362,
+ 32,
+ 7243,
+ 32,
+ 7391,
+ 32,
+ 11546,
+ 32,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 90434,
+ 519,
+ 0,
+ 1,
+ 74433,
+ 32,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 955506,
+ 213312,
+ 0,
+ 2,
+ 270652,
+ 22588,
+ 4,
+ 1457325,
+ 64566,
+ 4,
+ 20467,
+ 1,
+ 4,
+ 0,
+ 141992,
+ 32,
+ 100788,
+ 420,
+ 1,
+ 1,
+ 81663,
+ 32,
+ 59498,
+ 32,
+ 20142,
+ 32,
+ 24588,
+ 32,
+ 20744,
+ 32,
+ 25933,
+ 32,
+ 24623,
+ 32,
+ 43053543,
+ 10,
+ 53384111,
+ 14333,
+ 10,
+ 43574283,
+ 26308,
+ 10,
+ 1293828,
+ 28716,
+ 63,
+ 0,
+ 1,
+ 1006041,
+ 43623,
+ 251,
+ 0,
+ 1,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 962335,
+ 18,
+ 2780678,
+ 6,
+ 442008,
+ 1,
+ 52538055,
+ 3756,
+ 18,
+ 267929,
+ 18,
+ 76433006,
+ 8868,
+ 18,
+ 52948122,
+ 18,
+ 1995836,
+ 36,
+ 3227919,
+ 12,
+ 901022,
+ 1,
+ 166917843,
+ 4307,
+ 36,
+ 284546,
+ 36,
+ 158221314,
+ 26549,
+ 36,
+ 74698472,
+ 36,
+ 333849714,
+ 1,
+ 254006273,
+ 72,
+ 2174038,
+ 72,
+ 2261318,
+ 64571,
+ 4,
+ 207616,
+ 8310,
+ 4,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 107878,
+ 680,
+ 0,
+ 1,
+ 95336,
+ 1,
+ 281145,
+ 18848,
+ 0,
+ 1,
+ 180194,
+ 159,
+ 1,
+ 1,
+ 158519,
+ 8942,
+ 0,
+ 1,
+ 159378,
+ 8813,
+ 0,
+ 1,
+ 107490,
+ 3298,
+ 1,
+ 106057,
+ 655,
+ 1,
+ 1964219,
+ 24520,
+ 3,
+ 607153,
+ 231697,
+ 53144,
+ 0,
+ 1,
+ 116711,
+ 1957,
+ 4,
+ 231883,
+ 10,
+ 1000,
+ 24838,
+ 7,
+ 1,
+ 232010,
+ 32,
+ 321837444,
+ 25087669,
+ 18,
+ 617887431,
+ 67302824,
+ 36,
+ 356924,
+ 18413,
+ 45,
+ 21,
+ 219951,
+ 9444,
+ 1,
+ 1000,
+ 172116,
+ 183150,
+ 6,
+ 24,
+ 21,
+ 213283,
+ 618401,
+ 1998,
+ 28258,
+ 1,
+ 1000,
+ 38159,
+ 2,
+ 22,
+ 1000,
+ 95933,
+ 1,
+ 1,
+ 11,
+ 1000,
+ 277577,
+ 12,
+ 21
+ ],
+ "PlutusV3": [
+ 100788,
+ 420,
+ 1,
+ 1,
+ 1000,
+ 173,
+ 0,
+ 1,
+ 1000,
+ 59957,
+ 4,
+ 1,
+ 11183,
+ 32,
+ 201305,
+ 8356,
+ 4,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 100,
+ 100,
+ 16000,
+ 100,
+ 94375,
+ 32,
+ 132994,
+ 32,
+ 61462,
+ 4,
+ 72010,
+ 178,
+ 0,
+ 1,
+ 22151,
+ 32,
+ 91189,
+ 769,
+ 4,
+ 2,
+ 85848,
+ 123203,
+ 7305,
+ -900,
+ 1716,
+ 960,
+ 57,
+ 85848,
+ 0,
+ 1,
+ 1,
+ 1000,
+ 42921,
+ 4,
+ 2,
+ 30623,
+ 28755,
+ 75,
+ 1,
+ 898148,
+ 27279,
+ 1,
+ 51775,
+ 558,
+ 1,
+ 39184,
+ 1000,
+ 60594,
+ 1,
+ 141895,
+ 32,
+ 83150,
+ 32,
+ 15299,
+ 32,
+ 76049,
+ 1,
+ 13169,
+ 4,
+ 22100,
+ 10,
+ 28999,
+ 74,
+ 1,
+ 28999,
+ 74,
+ 1,
+ 43285,
+ 552,
+ 1,
+ 44749,
+ 541,
+ 1,
+ 33852,
+ 32,
+ 68246,
+ 32,
+ 72362,
+ 32,
+ 7243,
+ 32,
+ 7391,
+ 32,
+ 11546,
+ 32,
+ 85848,
+ 123203,
+ 7305,
+ -900,
+ 1716,
+ 960,
+ 57,
+ 85848,
+ 0,
+ 1,
+ 90434,
+ 519,
+ 0,
+ 1,
+ 74433,
+ 32,
+ 85848,
+ 123203,
+ 7305,
+ -900,
+ 1716,
+ 960,
+ 57,
+ 85848,
+ 0,
+ 1,
+ 1,
+ 85848,
+ 123203,
+ 7305,
+ -900,
+ 1716,
+ 960,
+ 57,
+ 85848,
+ 0,
+ 1,
+ 955506,
+ 213312,
+ 0,
+ 2,
+ 270652,
+ 22588,
+ 4,
+ 1457325,
+ 64566,
+ 4,
+ 20467,
+ 1,
+ 4,
+ 0,
+ 141992,
+ 32,
+ 100788,
+ 420,
+ 1,
+ 1,
+ 81663,
+ 32,
+ 59498,
+ 32,
+ 20142,
+ 32,
+ 24588,
+ 32,
+ 20744,
+ 32,
+ 25933,
+ 32,
+ 24623,
+ 32,
+ 43053543,
+ 10,
+ 53384111,
+ 14333,
+ 10,
+ 43574283,
+ 26308,
+ 10,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 962335,
+ 18,
+ 2780678,
+ 6,
+ 442008,
+ 1,
+ 52538055,
+ 3756,
+ 18,
+ 267929,
+ 18,
+ 76433006,
+ 8868,
+ 18,
+ 52948122,
+ 18,
+ 1995836,
+ 36,
+ 3227919,
+ 12,
+ 901022,
+ 1,
+ 166917843,
+ 4307,
+ 36,
+ 284546,
+ 36,
+ 158221314,
+ 26549,
+ 36,
+ 74698472,
+ 36,
+ 333849714,
+ 1,
+ 254006273,
+ 72,
+ 2174038,
+ 72,
+ 2261318,
+ 64571,
+ 4,
+ 207616,
+ 8310,
+ 4,
+ 1293828,
+ 28716,
+ 63,
+ 0,
+ 1,
+ 1006041,
+ 43623,
+ 251,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 107878,
+ 680,
+ 0,
+ 1,
+ 95336,
+ 1,
+ 281145,
+ 18848,
+ 0,
+ 1,
+ 180194,
+ 159,
+ 1,
+ 1,
+ 158519,
+ 8942,
+ 0,
+ 1,
+ 159378,
+ 8813,
+ 0,
+ 1,
+ 107490,
+ 3298,
+ 1,
+ 106057,
+ 655,
+ 1,
+ 1964219,
+ 24520,
+ 3,
+ 607153,
+ 231697,
+ 53144,
+ 0,
+ 1,
+ 116711,
+ 1957,
+ 4,
+ 231883,
+ 10,
+ 1000,
+ 24838,
+ 7,
+ 1,
+ 232010,
+ 32,
+ 321837444,
+ 25087669,
+ 18,
+ 617887431,
+ 67302824,
+ 36,
+ 356924,
+ 18413,
+ 45,
+ 21,
+ 219951,
+ 9444,
+ 1,
+ 1000,
+ 172116,
+ 183150,
+ 6,
+ 24,
+ 21,
+ 213283,
+ 618401,
+ 1998,
+ 28258,
+ 1,
+ 1000,
+ 38159,
+ 2,
+ 22,
+ 1000,
+ 95933,
+ 1,
+ 1,
+ 11,
+ 1000,
+ 277577,
+ 12,
+ 21
+ ]
+}
diff --git a/applications/cli/docker/application.properties b/applications/cli/docker/application.properties
index 9e80581f..5319999a 100644
--- a/applications/cli/docker/application.properties
+++ b/applications/cli/docker/application.properties
@@ -2,10 +2,11 @@ spring.config.import=optional:file:/app/config/node.properties
cardano.cli.path=/app/cardano-bin
yaci.store.folder=/app/store
+yano.folder=/app/yano
ogmios.folder=/app/ogmios
kupo.folder=/app/kupo
local.cluster.home=/clusters/nodes
pool.keys.home=/clusters/pool-keys
spring.shell.config.location=/clusters
server.port=10000
-
+yaci.cli.plutus-costmodels-path=/app/config
diff --git a/applications/cli/docker/download-amd64.sh b/applications/cli/docker/download-amd64.sh
index cdbdb738..1ca0ce47 100644
--- a/applications/cli/docker/download-amd64.sh
+++ b/applications/cli/docker/download-amd64.sh
@@ -1,5 +1,5 @@
-file=cardano-node-10.5.0-linux.tar.gz
-wget https://github.com/IntersectMBO/cardano-node/releases/download/10.5.0/cardano-node-10.5.0-linux.tar.gz
+file=cardano-node-11.0.1-linux-amd64.tar.gz
+wget https://github.com/IntersectMBO/cardano-node/releases/download/11.0.1/cardano-node-11.0.1-linux-amd64.tar.gz
mkdir /app/cardano-bin
diff --git a/applications/cli/docker/download-arm64.sh b/applications/cli/docker/download-arm64.sh
index 0d81adef..81020997 100755
--- a/applications/cli/docker/download-arm64.sh
+++ b/applications/cli/docker/download-arm64.sh
@@ -1,16 +1,11 @@
-file=cardano-10_5_0-aarch64-static-musl-ghc_9101.tar.zst
-dir=cardano-10_5_0-aarch64-static-musl-ghc_9101
-wget https://github.com/armada-alliance/cardano-node-binaries/raw/main/static-binaries/$file?raw=true -O - | tar -I zstd -xv
+file=cardano-node-11.0.1-linux-arm64.tar.gz
+wget https://github.com/IntersectMBO/cardano-node/releases/download/11.0.1/cardano-node-11.0.1-linux-arm64.tar.gz
-#unzip $file
-mv $dir cardano-node
-mv cardano-node /app/cardano-bin/
-#rm $file
+mkdir /app/cardano-bin
-#submit_api_file=cardano-submit-api-3_2_2.zip
-#wget https://github.com/armada-alliance/cardano-node-binaries/raw/main/static-binaries/cardano-submit-api/$submit_api_file
-#
-#unzip $submit_api_file
-#mv cardano-submit-api /app/cardano-bin/
-#
-#rm $submit_api_file
+tar zxvf $file -C /app/cardano-bin
+
+mv /app/cardano-bin/bin/* /app/cardano-bin/
+rm -rf /app/cardano-bin/bin
+
+rm $file
diff --git a/applications/cli/docker/download-ogmios.sh b/applications/cli/docker/download-ogmios.sh
index 53c80546..93f34bd9 100644
--- a/applications/cli/docker/download-ogmios.sh
+++ b/applications/cli/docker/download-ogmios.sh
@@ -15,7 +15,7 @@ case $1 in
esac
-version=v6.13.0
+version=v6.14.0
file=ogmios-${version}-${SUFFIX}-linux.zip
wget https://github.com/CardanoSolutions/ogmios/releases/download/${version}/$file
diff --git a/applications/cli/docker/plutus-costmodels-v10.json b/applications/cli/docker/plutus-costmodels-v10.json
new file mode 100644
index 00000000..f07d0a17
--- /dev/null
+++ b/applications/cli/docker/plutus-costmodels-v10.json
@@ -0,0 +1,646 @@
+{
+ "PlutusV1": [
+ 100788,
+ 420,
+ 1,
+ 1,
+ 1000,
+ 173,
+ 0,
+ 1,
+ 1000,
+ 59957,
+ 4,
+ 1,
+ 11183,
+ 32,
+ 201305,
+ 8356,
+ 4,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 100,
+ 100,
+ 16000,
+ 100,
+ 94375,
+ 32,
+ 132994,
+ 32,
+ 61462,
+ 4,
+ 72010,
+ 178,
+ 0,
+ 1,
+ 22151,
+ 32,
+ 91189,
+ 769,
+ 4,
+ 2,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 1000,
+ 42921,
+ 4,
+ 2,
+ 24548,
+ 29498,
+ 38,
+ 1,
+ 898148,
+ 27279,
+ 1,
+ 51775,
+ 558,
+ 1,
+ 39184,
+ 1000,
+ 60594,
+ 1,
+ 141895,
+ 32,
+ 83150,
+ 32,
+ 15299,
+ 32,
+ 76049,
+ 1,
+ 13169,
+ 4,
+ 22100,
+ 10,
+ 28999,
+ 74,
+ 1,
+ 28999,
+ 74,
+ 1,
+ 43285,
+ 552,
+ 1,
+ 44749,
+ 541,
+ 1,
+ 33852,
+ 32,
+ 68246,
+ 32,
+ 72362,
+ 32,
+ 7243,
+ 32,
+ 7391,
+ 32,
+ 11546,
+ 32,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 90434,
+ 519,
+ 0,
+ 1,
+ 74433,
+ 32,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 270652,
+ 22588,
+ 4,
+ 1457325,
+ 64566,
+ 4,
+ 20467,
+ 1,
+ 4,
+ 0,
+ 141992,
+ 32,
+ 100788,
+ 420,
+ 1,
+ 1,
+ 81663,
+ 32,
+ 59498,
+ 32,
+ 20142,
+ 32,
+ 24588,
+ 32,
+ 20744,
+ 32,
+ 25933,
+ 32,
+ 24623,
+ 32,
+ 53384111,
+ 14333,
+ 10
+ ],
+ "PlutusV2": [
+ 100788,
+ 420,
+ 1,
+ 1,
+ 1000,
+ 173,
+ 0,
+ 1,
+ 1000,
+ 59957,
+ 4,
+ 1,
+ 11183,
+ 32,
+ 201305,
+ 8356,
+ 4,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 100,
+ 100,
+ 16000,
+ 100,
+ 94375,
+ 32,
+ 132994,
+ 32,
+ 61462,
+ 4,
+ 72010,
+ 178,
+ 0,
+ 1,
+ 22151,
+ 32,
+ 91189,
+ 769,
+ 4,
+ 2,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 1000,
+ 42921,
+ 4,
+ 2,
+ 24548,
+ 29498,
+ 38,
+ 1,
+ 898148,
+ 27279,
+ 1,
+ 51775,
+ 558,
+ 1,
+ 39184,
+ 1000,
+ 60594,
+ 1,
+ 141895,
+ 32,
+ 83150,
+ 32,
+ 15299,
+ 32,
+ 76049,
+ 1,
+ 13169,
+ 4,
+ 22100,
+ 10,
+ 28999,
+ 74,
+ 1,
+ 28999,
+ 74,
+ 1,
+ 43285,
+ 552,
+ 1,
+ 44749,
+ 541,
+ 1,
+ 33852,
+ 32,
+ 68246,
+ 32,
+ 72362,
+ 32,
+ 7243,
+ 32,
+ 7391,
+ 32,
+ 11546,
+ 32,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 90434,
+ 519,
+ 0,
+ 1,
+ 74433,
+ 32,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 85848,
+ 228465,
+ 122,
+ 0,
+ 1,
+ 1,
+ 955506,
+ 213312,
+ 0,
+ 2,
+ 270652,
+ 22588,
+ 4,
+ 1457325,
+ 64566,
+ 4,
+ 20467,
+ 1,
+ 4,
+ 0,
+ 141992,
+ 32,
+ 100788,
+ 420,
+ 1,
+ 1,
+ 81663,
+ 32,
+ 59498,
+ 32,
+ 20142,
+ 32,
+ 24588,
+ 32,
+ 20744,
+ 32,
+ 25933,
+ 32,
+ 24623,
+ 32,
+ 43053543,
+ 10,
+ 53384111,
+ 14333,
+ 10,
+ 43574283,
+ 26308,
+ 10
+ ],
+ "PlutusV3": [
+ 100788,
+ 420,
+ 1,
+ 1,
+ 1000,
+ 173,
+ 0,
+ 1,
+ 1000,
+ 59957,
+ 4,
+ 1,
+ 11183,
+ 32,
+ 201305,
+ 8356,
+ 4,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 100,
+ 100,
+ 16000,
+ 100,
+ 94375,
+ 32,
+ 132994,
+ 32,
+ 61462,
+ 4,
+ 72010,
+ 178,
+ 0,
+ 1,
+ 22151,
+ 32,
+ 91189,
+ 769,
+ 4,
+ 2,
+ 85848,
+ 123203,
+ 7305,
+ -900,
+ 1716,
+ 549,
+ 57,
+ 85848,
+ 0,
+ 1,
+ 1,
+ 1000,
+ 42921,
+ 4,
+ 2,
+ 24548,
+ 29498,
+ 38,
+ 1,
+ 898148,
+ 27279,
+ 1,
+ 51775,
+ 558,
+ 1,
+ 39184,
+ 1000,
+ 60594,
+ 1,
+ 141895,
+ 32,
+ 83150,
+ 32,
+ 15299,
+ 32,
+ 76049,
+ 1,
+ 13169,
+ 4,
+ 22100,
+ 10,
+ 28999,
+ 74,
+ 1,
+ 28999,
+ 74,
+ 1,
+ 43285,
+ 552,
+ 1,
+ 44749,
+ 541,
+ 1,
+ 33852,
+ 32,
+ 68246,
+ 32,
+ 72362,
+ 32,
+ 7243,
+ 32,
+ 7391,
+ 32,
+ 11546,
+ 32,
+ 85848,
+ 123203,
+ 7305,
+ -900,
+ 1716,
+ 549,
+ 57,
+ 85848,
+ 0,
+ 1,
+ 90434,
+ 519,
+ 0,
+ 1,
+ 74433,
+ 32,
+ 85848,
+ 123203,
+ 7305,
+ -900,
+ 1716,
+ 549,
+ 57,
+ 85848,
+ 0,
+ 1,
+ 1,
+ 85848,
+ 123203,
+ 7305,
+ -900,
+ 1716,
+ 549,
+ 57,
+ 85848,
+ 0,
+ 1,
+ 955506,
+ 213312,
+ 0,
+ 2,
+ 270652,
+ 22588,
+ 4,
+ 1457325,
+ 64566,
+ 4,
+ 20467,
+ 1,
+ 4,
+ 0,
+ 141992,
+ 32,
+ 100788,
+ 420,
+ 1,
+ 1,
+ 81663,
+ 32,
+ 59498,
+ 32,
+ 20142,
+ 32,
+ 24588,
+ 32,
+ 20744,
+ 32,
+ 25933,
+ 32,
+ 24623,
+ 32,
+ 43053543,
+ 10,
+ 53384111,
+ 14333,
+ 10,
+ 43574283,
+ 26308,
+ 10,
+ 16000,
+ 100,
+ 16000,
+ 100,
+ 962335,
+ 18,
+ 2780678,
+ 6,
+ 442008,
+ 1,
+ 52538055,
+ 3756,
+ 18,
+ 267929,
+ 18,
+ 76433006,
+ 8868,
+ 18,
+ 52948122,
+ 18,
+ 1995836,
+ 36,
+ 3227919,
+ 12,
+ 901022,
+ 1,
+ 166917843,
+ 4307,
+ 36,
+ 284546,
+ 36,
+ 158221314,
+ 26549,
+ 36,
+ 74698472,
+ 36,
+ 333849714,
+ 1,
+ 254006273,
+ 72,
+ 2174038,
+ 72,
+ 2261318,
+ 64571,
+ 4,
+ 207616,
+ 8310,
+ 4,
+ 1293828,
+ 28716,
+ 63,
+ 0,
+ 1,
+ 1006041,
+ 43623,
+ 251,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 100181,
+ 726,
+ 719,
+ 0,
+ 1,
+ 107878,
+ 680,
+ 0,
+ 1,
+ 95336,
+ 1,
+ 281145,
+ 18848,
+ 0,
+ 1,
+ 180194,
+ 159,
+ 1,
+ 1,
+ 158519,
+ 8942,
+ 0,
+ 1,
+ 159378,
+ 8813,
+ 0,
+ 1,
+ 107490,
+ 3298,
+ 1,
+ 106057,
+ 655,
+ 1,
+ 1964219,
+ 24520,
+ 3
+ ]
+}
diff --git a/applications/cli/docker/plutus-costmodels-v11.json b/applications/cli/docker/plutus-costmodels-v11.json
new file mode 100644
index 00000000..cc725ecd
--- /dev/null
+++ b/applications/cli/docker/plutus-costmodels-v11.json
@@ -0,0 +1,73 @@
+{
+ "PlutusV1": [
+ 100788, 420, 1, 1, 1000, 173, 0, 1, 1000, 59957,
+ 4, 1, 11183, 32, 201305, 8356, 4, 16000, 100, 16000,
+ 100, 16000, 100, 16000, 100, 16000, 100, 16000, 100, 100,
+ 100, 16000, 100, 94375, 32, 132994, 32, 61462, 4, 72010,
+ 178, 0, 1, 22151, 32, 91189, 769, 4, 2, 85848,
+ 228465, 122, 0, 1, 1, 1000, 42921, 4, 2, 24548,
+ 29498, 38, 1, 898148, 27279, 1, 51775, 558, 1, 39184,
+ 1000, 60594, 1, 141895, 32, 83150, 32, 15299, 32, 76049,
+ 1, 13169, 4, 22100, 10, 28999, 74, 1, 28999, 74,
+ 1, 43285, 552, 1, 44749, 541, 1, 33852, 32, 68246,
+ 32, 72362, 32, 7243, 32, 7391, 32, 11546, 32, 85848,
+ 228465, 122, 0, 1, 1, 90434, 519, 0, 1, 74433,
+ 32, 85848, 228465, 122, 0, 1, 1, 85848, 228465, 122,
+ 0, 1, 1, 270652, 22588, 4, 1457325, 64566, 4, 20467,
+ 1, 4, 0, 141992, 32, 100788, 420, 1, 1, 81663,
+ 32, 59498, 32, 20142, 32, 24588, 32, 20744, 32, 25933,
+ 32, 24623, 32, 53384111, 14333, 10
+ ],
+ "PlutusV2": [
+ 100788, 420, 1, 1, 1000, 173, 0, 1, 1000, 59957,
+ 4, 1, 11183, 32, 201305, 8356, 4, 16000, 100, 16000,
+ 100, 16000, 100, 16000, 100, 16000, 100, 16000, 100, 100,
+ 100, 16000, 100, 94375, 32, 132994, 32, 61462, 4, 72010,
+ 178, 0, 1, 22151, 32, 91189, 769, 4, 2, 85848,
+ 228465, 122, 0, 1, 1, 1000, 42921, 4, 2, 24548,
+ 29498, 38, 1, 898148, 27279, 1, 51775, 558, 1, 39184,
+ 1000, 60594, 1, 141895, 32, 83150, 32, 15299, 32, 76049,
+ 1, 13169, 4, 22100, 10, 28999, 74, 1, 28999, 74,
+ 1, 43285, 552, 1, 44749, 541, 1, 33852, 32, 68246,
+ 32, 72362, 32, 7243, 32, 7391, 32, 11546, 32, 85848,
+ 228465, 122, 0, 1, 1, 90434, 519, 0, 1, 74433,
+ 32, 85848, 228465, 122, 0, 1, 1, 85848, 228465, 122,
+ 0, 1, 1, 955506, 213312, 0, 2, 270652, 22588, 4,
+ 1457325, 64566, 4, 20467, 1, 4, 0, 141992, 32, 100788,
+ 420, 1, 1, 81663, 32, 59498, 32, 20142, 32, 24588,
+ 32, 20744, 32, 25933, 32, 24623, 32, 43053543, 10, 53384111,
+ 14333, 10, 43574283, 26308, 10
+ ],
+ "PlutusV3": [
+ 100788, 420, 1, 1, 1000, 173, 0, 1, 1000, 59957,
+ 4, 1, 11183, 32, 201305, 8356, 4, 16000, 100, 16000,
+ 100, 16000, 100, 16000, 100, 16000, 100, 16000, 100, 100,
+ 100, 16000, 100, 94375, 32, 132994, 32, 61462, 4, 72010,
+ 178, 0, 1, 22151, 32, 91189, 769, 4, 2, 85848,
+ 123203, 7305, -900, 1716, 549, 57, 85848, 0, 1, 1,
+ 1000, 42921, 4, 2, 24548, 29498, 38, 1, 898148, 27279,
+ 1, 51775, 558, 1, 39184, 1000, 60594, 1, 141895, 32,
+ 83150, 32, 15299, 32, 76049, 1, 13169, 4, 22100, 10,
+ 28999, 74, 1, 28999, 74, 1, 43285, 552, 1, 44749,
+ 541, 1, 33852, 32, 68246, 32, 72362, 32, 7243, 32,
+ 7391, 32, 11546, 32, 85848, 123203, 7305, -900, 1716, 549,
+ 57, 85848, 0, 1, 90434, 519, 0, 1, 74433, 32,
+ 85848, 123203, 7305, -900, 1716, 549, 57, 85848, 0, 1,
+ 1, 85848, 123203, 7305, -900, 1716, 549, 57, 85848, 0,
+ 1, 955506, 213312, 0, 2, 270652, 22588, 4, 1457325, 64566,
+ 4, 20467, 1, 4, 0, 141992, 32, 100788, 420, 1,
+ 1, 81663, 32, 59498, 32, 20142, 32, 24588, 32, 20744,
+ 32, 25933, 32, 24623, 32, 43053543, 10, 53384111, 14333, 10,
+ 43574283, 26308, 10, 16000, 100, 16000, 100, 962335, 18, 2780678,
+ 6, 442008, 1, 52538055, 3756, 18, 267929, 18, 76433006, 8868,
+ 18, 52948122, 18, 1995836, 36, 3227919, 12, 901022, 1, 166917843,
+ 4307, 36, 284546, 36, 158221314, 26549, 36, 74698472, 36, 333849714,
+ 1, 254006273, 72, 2174038, 72, 2261318, 64571, 4, 207616, 8310,
+ 4, 1293828, 28716, 63, 0, 1, 1006041, 43623, 251, 0,
+ 1, 100181, 726, 719, 0, 1, 100181, 726, 719, 0,
+ 1, 100181, 726, 719, 0, 1, 107878, 680, 0, 1,
+ 95336, 1, 281145, 18848, 0, 1, 180194, 159, 1, 1,
+ 158519, 8942, 0, 1, 159378, 8813, 0, 1, 107490, 3298,
+ 1, 106057, 655, 1, 1964219, 24520, 3
+ ]
+}
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/commands/common/DownloadService.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/commands/common/DownloadService.java
index 1c13f7ad..b88d5265 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/commands/common/DownloadService.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/commands/common/DownloadService.java
@@ -31,6 +31,7 @@ public class DownloadService {
private final static String YACI_STORE_DOWNLOAD_URL = "https://github.com/bloxbean/yaci-store/releases/download";
private final static String OGMIOS_DOWNLOAD_URL = "https://github.com/CardanoSolutions/ogmios/releases/download";
private final static String KUPO_DOWNLOAD_URL = "https://github.com/CardanoSolutions/kupo/releases/download";
+ private final static String YANO_DOWNLOAD_URL = "https://github.com/bloxbean/yano/releases/download";
private final ClusterConfig clusterConfig;
@@ -67,6 +68,15 @@ public class DownloadService {
@Value("${kupo.url:#{null}}")
private String kupoUrl;
+ @Value("${yano.version:#{null}}")
+ private String yanoVersion;
+
+ @Value("${yano.tag:#{null}}")
+ private String yanoTag;
+
+ @Value("${yano.url:#{null}}")
+ private String yanoUrl;
+
public boolean downloadNode(boolean overwrite) {
String downloadPath = resolveNodeDownloadPath();
@@ -347,6 +357,80 @@ public boolean downloadKupo(boolean overwrite) {
return false;
}
+ public boolean downloadYano(boolean overwrite) {
+ String downloadPath = resolveYanoDownloadPath();
+
+ if (downloadPath == null) {
+ writeLn(error("Download URL for Yano is not set. Please set the download URL in download.properties"));
+ return false;
+ }
+
+ Path yanoExec = Path.of(clusterConfig.getYanoHome(), "yano");
+
+ if (yanoExec.toFile().exists()) {
+ if (!overwrite) {
+ writeLn(info("Yano already exists in %s", yanoExec.toFile().getAbsolutePath()));
+ writeLn(info("Use --overwrite to overwrite the existing yano"));
+ return false;
+ } else {
+ deleteExistingDir("yano", clusterConfig.getYanoHome());
+ }
+ }
+
+ String targetDir = clusterConfig.getYanoHome();
+ var downloadedFile = download("yano", downloadPath, targetDir, "yano-native.zip");
+ if (downloadedFile != null) {
+ try {
+ // Extract full zip to a temp folder, then move contents to yanoHome
+ var tmpFolder = Paths.get(clusterConfig.getYanoHome(), "tmp");
+ extractZip(downloadedFile.toFile().getAbsolutePath(), tmpFolder.toFile().getAbsolutePath());
+
+ // The zip contains a single folder (e.g. yano-native-0.1.0-pre1-macos-arm64/)
+ // Move all its contents to yanoHome
+ File[] extractedItems = tmpFolder.toFile().listFiles();
+ File extractedRoot = null;
+ if (extractedItems != null) {
+ for (File f : extractedItems) {
+ if (f.isDirectory() && f.getName().startsWith("yano")) {
+ extractedRoot = f;
+ break;
+ }
+ }
+ }
+
+ if (extractedRoot != null) {
+ // Copy entire contents (binary, config, scripts) to yanoHome
+ File[] contents = extractedRoot.listFiles();
+ if (contents != null) {
+ Path yanoHome = Path.of(clusterConfig.getYanoHome());
+ for (File item : contents) {
+ Path dest = yanoHome.resolve(item.getName());
+ if (item.isDirectory()) {
+ FileUtils.copyDirectory(item, dest.toFile());
+ } else {
+ Files.copy(item.toPath(), dest, StandardCopyOption.REPLACE_EXISTING);
+ }
+ }
+ }
+ writeLn(success("Extracted yano to " + clusterConfig.getYanoHome()));
+ } else {
+ writeLn(error("yano folder not found in the extracted archive"));
+ }
+
+ setExecutablePermission(yanoExec.toFile().getAbsolutePath());
+ FileUtils.deleteDirectory(tmpFolder.toFile());
+ Files.deleteIfExists(downloadedFile);
+ return true;
+ } catch (IOException e) {
+ writeLn(error("Error extracting yano: " + e.getMessage()));
+ }
+ } else {
+ writeLn(error("Download failed for yano"));
+ }
+
+ return false;
+ }
+
private void setExecutablePermission(String path) {
File file = new File(path);
if (!file.exists()) return;
@@ -483,10 +567,22 @@ private String resolveNodeDownloadPath() {
writeLn(error("Unsupported OS : " + System.getProperty("os.name")));
}
+ String arch = System.getProperty("os.arch");
+ String cpuArch = null;
+ if (arch.startsWith("aarch") || arch.startsWith("arm")) {
+ cpuArch = "arm64";
+ } else{
+ cpuArch = "amd64";
+ }
+
+ //Just a workaround, as 10.6.2 macos arm binary is not working.
+ if (osPrefix.equals("macos"))
+ cpuArch = "amd64";
+
if (osPrefix == null)
return null;
- String url = NODE_DOWNLOAD_URL + "/" + nodeVersion + "/cardano-node-" + nodeVersion + "-" + osPrefix + ".tar.gz";
+ String url = NODE_DOWNLOAD_URL + "/" + nodeVersion + "/cardano-node-" + nodeVersion + "-" + osPrefix + "-" + cpuArch + ".tar.gz";
return url;
}
@@ -608,6 +704,40 @@ private String resolveKupoDownloadPath() {
return url;
}
+ private String resolveYanoDownloadPath() {
+ if (!StringUtils.isEmpty(yanoUrl)) {
+ return yanoUrl;
+ }
+
+ if (StringUtils.isEmpty(yanoVersion) || StringUtils.isEmpty(yanoTag)) {
+ writeLn(error("Yano version/tag is not set. Please set yano.version and yano.tag or yano.url in download.properties"));
+ return null;
+ }
+
+ String osPrefix = null;
+ if (SystemUtils.IS_OS_MAC) {
+ osPrefix = "macos";
+ } else if (SystemUtils.IS_OS_LINUX) {
+ osPrefix = "linux";
+ } else {
+ writeLn(error("Unsupported OS : " + System.getProperty("os.name")));
+ }
+
+ String arch = System.getProperty("os.arch");
+ String cpuArch;
+ if (arch.startsWith("aarch") || arch.startsWith("arm")) {
+ cpuArch = "arm64";
+ } else {
+ cpuArch = "x64";
+ }
+
+ if (osPrefix == null)
+ return null;
+
+ // Release asset pattern: yano-native-{version}-{os}-{arch}.zip
+ return YANO_DOWNLOAD_URL + "/" + yanoTag + "/yano-native-" + yanoVersion + "-" + osPrefix + "-" + cpuArch + ".zip";
+ }
+
private void deleteExistingDir(String componentName, String componentHome) {
Objects.requireNonNull(componentHome, "Component home cannot be null");
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/commands/general/DownloadCommand.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/commands/general/DownloadCommand.java
index 71f804b6..81bf2552 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/commands/general/DownloadCommand.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/commands/general/DownloadCommand.java
@@ -25,7 +25,7 @@ public class DownloadCommand {
@ShellMethod(value = "Download", key = "download")
@ShellMethodAvailability({"nonDockerCommandAvailability"})
public boolean download(
- @ShellOption(value = {"--component", "-c"}, defaultValue = "all", help = "Provide list of components separated by space. Components: node,ogmios,kupo,yaci-store,yaci-store-jar") String[] components,
+ @ShellOption(value = {"--component", "-c"}, defaultValue = "all", help = "Provide list of components separated by space. Components: node,ogmios,kupo,yaci-store,yaci-store-jar,yano") String[] components,
@ShellOption(value = {"-o", "--overwrite"}, defaultValue = "false", help = "Overwrite existing installation. default: false") boolean overwrite
) {
@@ -63,6 +63,11 @@ public boolean download(
validComponent = true;
}
+ if (componentList.contains("all") || componentList.contains("yano")) {
+ downloadService.downloadYano(overwrite);
+ validComponent = true;
+ }
+
if (!validComponent) {
writeLn(error("Invalid components : " + componentList));
return false;
@@ -85,11 +90,11 @@ public void downloadAndStart(
@ShellOption(value = {"--port"}, help = "Node port (Used with --create option only)", defaultValue = "3001") int port,
@ShellOption(value = {"--submit-api-port"}, help = "Submit Api Port", defaultValue = "8090") int submitApiPort,
@ShellOption(value = {"-s", "--slot-length"}, help = "Slot Length in sec. (0.1 to ..)", defaultValue = "1") double slotLength,
- @ShellOption(value = {"-b", "--block-time"}, help = "Block time in sec. (1 - 20)", defaultValue = "1") double blockTime,
+ @ShellOption(value = {"-b", "--block-time"}, help = "Block time in sec. (0.1 - 20)", defaultValue = "1") double blockTime,
@ShellOption(value = {"-e", "--epoch-length"}, help = "No of slots in an epoch", defaultValue = "600") int epochLength,
@ShellOption(value = {"--genesis-profile"}, defaultValue = ShellOption.NULL,
help = "Use a pre-defined genesis profile (Options: zero_fee, zero_min_utxo_value, zero_fee_and_min_utxo_value)") GenesisProfile genesisProfile,
- @ShellOption(value = {"--enable-yaci-store"}, defaultValue = "false", help = "Enable Yaci Store. This will also enable Ogmios for Tx Evaluation") boolean enableYaciStore,
+ @ShellOption(value = {"--enable-yaci-store"}, defaultValue = "false", help = "Enable Yaci Store") boolean enableYaciStore,
@ShellOption(value = {"--enable-kupomios"}, defaultValue = "false", help= "Enable Ogmios and Kupo") boolean enableKupomios,
@ShellOption(value = {"--interactive"}, defaultValue="false", help="To start in interactive mode when 'up' command is passed as an arg to yaci-cli") boolean interactive,
@ShellOption(value = {"--tail"}, defaultValue="false", help="To tail the network when 'up' command is passed as an arg to yaci-cli. Only works in non-interactive mode.") boolean tail,
@@ -104,7 +109,7 @@ public void downloadAndStart(
if (enableYaciStore) {
applicationConfig.setYaciStoreEnabled(true);
- applicationConfig.setOgmiosEnabled(true);
+ applicationConfig.setOgmiosEnabled(false); //TODO -- Temporarily till Ogmios is ready
} else if (enableKupomios){
applicationConfig.setOgmiosEnabled(true);
applicationConfig.setKupoEnabled(true);
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterCommands.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterCommands.java
index 63ce2613..e45fb181 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterCommands.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterCommands.java
@@ -97,7 +97,7 @@ public void createCluster(@ShellOption(value = {"-n", "--name"}, defaultValue =
@ShellOption(value = {"--port"}, help = "Node port (Used with --create option only)", defaultValue = "3001") int port,
@ShellOption(value = {"--submit-api-port"}, help = "Submit Api Port", defaultValue = "8090") int submitApiPort,
@ShellOption(value = {"-s", "--slot-length"}, help = "Slot Length in sec. (0.1 to ..)", defaultValue = "1") double slotLength,
- @ShellOption(value = {"-b", "--block-time"}, help = "Block time in sec. (1 - 20)", defaultValue = "1") double blockTime,
+ @ShellOption(value = {"-b", "--block-time"}, help = "Block time in sec. (0.1 - 20)", defaultValue = "1") double blockTime,
@ShellOption(value = {"-e", "--epoch-length"}, help = "No of slots in an epoch", defaultValue = "600") int epochLength,
@ShellOption(value = {"-o", "--overwrite"}, defaultValue = "false", help = "Overwrite existing node directory. default: false") boolean overwrite,
@ShellOption(value = {"--start"}, defaultValue = "false", help = "Automatically start the node after create. default: false") boolean start,
@@ -116,6 +116,11 @@ public void createCluster(@ShellOption(value = {"-n", "--name"}, defaultValue =
return;
}
+ if (blockTime < 1 && slotLength > blockTime) {
+ slotLength = blockTime;
+ writeLn(info("Slot length adjusted to " + slotLength + " sec to match block time"));
+ }
+
if (slotLength > blockTime) {
writeLn(error("Slot length should be less than block time"));
return;
@@ -168,6 +173,7 @@ else if (era.equalsIgnoreCase("conway"))
.yaciStorePort(yaciStorePort)
.socatPort(socatPort)
.prometheusPort(prometheusPort)
+ .nodeMode(genesisConfig.getNodeMode())
.localMultiNodeEnabled(enableMultiNode)
.localMultiNodeStakeRatioFactor(stakeRatioFactor)
.build();
@@ -234,6 +240,18 @@ public void startLocalCluster() {
if (!runStatus.stared())
return;
+ // Ensure CommandContext.era is populated for downstream listeners and the
+ // waitForNextBlocks call below (both read CommandContext.INSTANCE.getEra()).
+ // The HTTP /devnet/reset path does not set era anywhere otherwise.
+ try {
+ ClusterInfo clusterInfo = localClusterService.getClusterInfo(clusterName);
+ if (clusterInfo != null && clusterInfo.getEra() != null) {
+ CommandContext.INSTANCE.setEra(clusterInfo.getEra());
+ }
+ } catch (IOException e) {
+ log.warn("Could not load cluster info to set era for {}", clusterName, e);
+ }
+
if (runStatus.isFirstRun()) {
publisher.publishEvent(new FirstRunDone(clusterName));
publisher.publishEvent(new ClusterStarted(clusterName));
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterConfig.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterConfig.java
index a522f1ba..4438f3da 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterConfig.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterConfig.java
@@ -51,6 +51,9 @@ public class ClusterConfig {
@Value("${kupo.folder:#{null}}")
private String kupoFolder;
+ @Value("${yano.folder:#{null}}")
+ private String yanoFolder;
+
@Value("${jre.folder:#{null}}")
private String jreFolder;
@@ -135,6 +138,13 @@ public Path getGenesisKeysFolder(String clusterName) {
return Path.of(getGenesisKeysHome(), clusterName);
}
+ public String getYanoHome() {
+ if (yanoFolder == null || !StringUtils.hasLength(yanoFolder.trim()))
+ return Path.of(getYaciCliHome(), COMPONENTS, "yano").toAbsolutePath().toString();
+ else
+ return Path.of(yanoFolder).toAbsolutePath().toString();
+ }
+
public String getJreHome() {
if (jreFolder == null || !StringUtils.hasLength(jreFolder.trim()))
return Path.of(getYaciCliHome(), COMPONENTS, "jre").toAbsolutePath().toString();
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterInfo.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterInfo.java
index 8f1cc14c..bfc97ab5 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterInfo.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterInfo.java
@@ -43,6 +43,14 @@ public class ClusterInfo {
@Builder.Default
private int prometheusPort=12798;
+ private int protocolMajorVer;
+ private NodeMode nodeMode;
+
+ @Builder.Default
+ private int yanoServerPort = 14447;
+ @Builder.Default
+ private int yanoHttpPort = 6060;
+
private boolean localMultiNodeEnabled;
private int localMultiNodeStakeRatioFactor;
}
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterPortInfoHelper.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterPortInfoHelper.java
index 4ba5997f..a4216467 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterPortInfoHelper.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterPortInfoHelper.java
@@ -38,6 +38,8 @@ public void printUrls(String clusteName, ClusterInfo clusterInfo) {
writeLn(infoLabel("Epoch Length", String.valueOf(clusterInfo.getEpochLength())));
writeLn(infoLabel("Security Param", String.valueOf(clusterInfo.getSecurityParam())));
writeLn(infoLabel("SlotsPerKESPeriod", String.valueOf(clusterInfo.getSlotsPerKESPeriod())));
+ NodeMode nodeMode = clusterInfo.getNodeMode() != null ? clusterInfo.getNodeMode() : NodeMode.HASKELL_ONLY;
+ writeLn(infoLabel("Node Mode", nodeMode.getValue()));
if (clusteName == null || !"default".equals(clusteName))
return;
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterService.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterService.java
index 5b93fccf..93733695 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterService.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterService.java
@@ -343,10 +343,13 @@ private void updateGenesis(Path clusterFolder, String clusterName, ClusterInfo c
srcConwayGenesisFile = clusterFolder.resolve("genesis-templates").resolve("conway-genesis.json");
}
+ Path srcDijkstraGenesisFile = clusterFolder.resolve("genesis-templates").resolve("dijkstra-genesis.json");
+
Path destByronGenesisFile = clusterFolder.resolve("node").resolve("genesis").resolve("byron-genesis.json");
Path destShelleyGenesisFile = clusterFolder.resolve("node").resolve("genesis").resolve("shelley-genesis.json");
Path destAlonzoGenesisFile = clusterFolder.resolve("node").resolve("genesis").resolve("alonzo-genesis.json");
Path destConwayGenesisFile = clusterFolder.resolve("node").resolve("genesis").resolve("conway-genesis.json");
+ Path destDijkstraGenesisFile = clusterFolder.resolve("node").resolve("genesis").resolve("dijkstra-genesis.json");
GenesisConfig genesisConfigCopy = genesisConfig.copy();
genesisConfigCopy.merge(customGenesisConfig.getMap());
@@ -375,11 +378,14 @@ private void updateGenesis(Path clusterFolder, String clusterName, ClusterInfo c
values.put("activeSlotsCoeff", String.valueOf(activeSlotsCoeff));
values.put("epochLength", String.valueOf(epochLength));
- //Check if protocol version should be minimun 9 and it's conway era
- if (era == Era.Conway && genesisConfigCopy.getProtocolMajorVer() < 9) {
- values.put("protocolMajorVer", 10);
- values.put("protocolMinorVer", 2);
+ //Check if protocol version should be minimum 9 and it's conway era
+ int resolvedProtocolMajorVer = genesisConfigCopy.getProtocolMajorVer();
+ if (era == Era.Conway && resolvedProtocolMajorVer < 9) {
+ resolvedProtocolMajorVer = 10;
+ values.put("protocolMajorVer", resolvedProtocolMajorVer);
+ values.put("protocolMinorVer", 0);
}
+ clusterInfo.setProtocolMajorVer(resolvedProtocolMajorVer);
//Derive security param
long securityParam = genesisConfigCopy.getSecurityParam();
@@ -407,6 +413,7 @@ private void updateGenesis(Path clusterFolder, String clusterName, ClusterInfo c
templateEngineHelper.replaceValues(srcShelleyGenesisFile, destShelleyGenesisFile, values);
templateEngineHelper.replaceValues(srcAlonzoGenesisFile, destAlonzoGenesisFile, values);
templateEngineHelper.replaceValues(srcConwayGenesisFile, destConwayGenesisFile, values);
+ templateEngineHelper.replaceValues(srcDijkstraGenesisFile, destDijkstraGenesisFile, values);
} catch (Exception e) {
throw new IOException(e);
}
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterStartService.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterStartService.java
index ef9763fc..c1c1f83f 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterStartService.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/ClusterStartService.java
@@ -8,8 +8,13 @@
import com.bloxbean.cardano.yacicli.localcluster.events.FirstRunDone;
import com.bloxbean.cardano.yacicli.localcluster.model.RunStatus;
import com.bloxbean.cardano.yacicli.localcluster.peer.LocalPeerService;
+import com.bloxbean.cardano.yacicli.localcluster.yano.YanoBootstrapService;
+import com.bloxbean.cardano.yacicli.localcluster.yano.YanoCompanionService;
+import com.bloxbean.cardano.yacicli.localcluster.yano.YanoGovernanceService;
+import com.bloxbean.cardano.yacicli.localcluster.yano.YanoService;
import com.bloxbean.cardano.yacicli.util.PortUtil;
import com.bloxbean.cardano.yacicli.util.ProcessUtil;
+import org.apache.commons.io.FileUtils;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.LongNode;
@@ -47,6 +52,10 @@ public class ClusterStartService {
private final GenesisConfig genesisConfig;
private final CustomGenesisConfig customGenesisConfig;
private final LocalPeerService localPeerService;
+ private final YanoCompanionService yanoCompanionService;
+ private final YanoService yanoService;
+ private final YanoBootstrapService yanoBootstrapService;
+ private final YanoGovernanceService yanoGovernanceService;
private ObjectMapper objectMapper = new ObjectMapper();
private List
processes = new ArrayList<>();
@@ -69,11 +78,88 @@ public RunStatus startCluster(ClusterInfo clusterInfo, Path clusterFolder, Consu
try {
boolean firstRun = checkIfFirstRun(clusterFolder);
+ boolean companionMode = NodeMode.COMPANION == clusterInfo.getNodeMode();
+ boolean yanoOnlyMode = NodeMode.YANO_ONLY == clusterInfo.getNodeMode();
+ boolean yanoPrimaryMode = NodeMode.YANO_PRIMARY == clusterInfo.getNodeMode();
+ boolean companionBootstrapDone = false;
+ String clusterName = CommandContext.INSTANCE.getProperty(ClusterConfig.CLUSTER_NAME);
+
if (clusterInfo.isMasterNode() && firstRun)
setupFirstRun(clusterInfo, clusterFolder, writer);
- if (clusterInfo.isLocalMultiNodeEnabled()) {
- String clusterName = CommandContext.INSTANCE.getProperty(ClusterConfig.CLUSTER_NAME);
+ // Companion mode: run Yano bootstrap before Haskell node
+ if (companionMode && firstRun) {
+ companionBootstrapDone = yanoCompanionService.bootstrap(clusterInfo, clusterFolder, writer);
+ if (!companionBootstrapDone) {
+ writer.accept(warn("Yano bootstrap failed. Continuing with haskell-only mode."));
+ }
+ }
+
+ if (yanoOnlyMode) {
+ // Yano-only: Yano is the sole block producer, no Haskell node
+ boolean yanoStarted = yanoService.start(clusterInfo, clusterFolder, false, writer);
+ if (!yanoStarted) {
+ writer.accept(error("Failed to start Yano."));
+ return new RunStatus(false, firstRun);
+ }
+
+ if (firstRun) {
+ int httpPort = clusterInfo.getYanoHttpPort();
+ if (!yanoBootstrapService.waitForReady(httpPort, writer)) {
+ writer.accept(error("Yano HTTP API not ready."));
+ yanoService.stop();
+ return new RunStatus(false, firstRun);
+ }
+
+ // Submit governance proposals via Yano's HTTP API
+ writer.accept(info("Submitting governance proposals via Yano..."));
+ yanoGovernanceService.submitCostModelGovernance(clusterInfo, clusterFolder, writer);
+ }
+
+ // No Haskell node, no submit-api, no handover
+ return new RunStatus(true, firstRun);
+ }
+
+ if (yanoPrimaryMode) {
+ // Like companion bootstrap but Yano stays as BP, Haskell stays as relay (no handover)
+ if (firstRun) {
+ boolean bootstrapDone = yanoCompanionService.bootstrap(clusterInfo, clusterFolder, writer);
+ if (!bootstrapDone) {
+ writer.accept(error("Yano bootstrap failed."));
+ return new RunStatus(false, firstRun);
+ }
+ } else {
+ boolean yanoStarted = yanoService.start(clusterInfo, clusterFolder, false, writer);
+ if (!yanoStarted) {
+ writer.accept(error("Failed to start Yano."));
+ return new RunStatus(false, firstRun);
+ }
+ if (!yanoBootstrapService.waitForReady(clusterInfo.getYanoHttpPort(), writer)) {
+ writer.accept(error("Yano HTTP API not ready."));
+ yanoService.stop();
+ return new RunStatus(false, firstRun);
+ }
+ }
+
+ Process nodeProcess = startNode(clusterFolder, clusterInfo, true, writer);
+ if (nodeProcess == null) {
+ writer.accept(error("Node process could not be started."));
+ yanoService.stop();
+ return new RunStatus(false, firstRun);
+ }
+ processes.add(nodeProcess);
+
+ Process submitApiProcess = startSubmitApi(clusterInfo, clusterFolder, writer);
+ if (submitApiProcess != null) processes.add(submitApiProcess);
+
+ // Relay needs time to chain-sync from Yano before N2C queries work
+ writer.accept(info("Waiting for Haskell relay to sync from Yano..."));
+ Thread.sleep(5000);
+
+ return new RunStatus(true, firstRun);
+ }
+
+ if (clusterInfo.isLocalMultiNodeEnabled() && !companionBootstrapDone) {
if (firstRun) {
localPeerService.handleFirstRun(new FirstRunDone(clusterName));
}
@@ -81,11 +167,49 @@ public RunStatus startCluster(ClusterInfo clusterInfo, Path clusterFolder, Consu
localPeerService.handleClusterStarted(new ClusterStarted(clusterName));
}
- Process nodeProcess = startNode(clusterFolder, clusterInfo, writer);
+ // In companion mode, start as relay first (no forging) to sync Yano's chain cleanly.
+ // A block producer would forge its own block at slot 1 (activeSlotsCoeff=1.0),
+ // creating a divergent chain that prevents chain-sync from Yano.
+ Process nodeProcess = startNode(clusterFolder, clusterInfo, companionBootstrapDone, writer);
if (nodeProcess == null) {
writer.accept(error("Node process could not be started."));
return new RunStatus(false, firstRun);
}
+ processes.add(nodeProcess);
+
+ // Companion mode handover: sync as relay, stop Yano, restart as block producer
+ if (companionBootstrapDone) {
+ yanoCompanionService.performHandover(clusterInfo, clusterFolder, writer);
+
+ // Stop relay node, restart as block producer (picks up synced chain from db)
+ writer.accept(info("Restarting Haskell node as block producer..."));
+ if (nodeProcess.isAlive()) {
+ nodeProcess.descendants().forEach(ProcessHandle::destroyForcibly);
+ nodeProcess.destroyForcibly();
+ nodeProcess.waitFor(15, TimeUnit.SECONDS);
+ }
+ processes.remove(nodeProcess);
+
+ // Remove stale socket so the BP instance can create a fresh one
+ Path socketPath = clusterFolder.resolve(ClusterConfig.NODE_FOLDER_PREFIX).resolve("node.sock");
+ Files.deleteIfExists(socketPath);
+
+ if (clusterInfo.isLocalMultiNodeEnabled()) {
+ localPeerService.preparePeersAfterCompanionHandover(clusterName, writer);
+ }
+
+ nodeProcess = startNode(clusterFolder, clusterInfo, false, writer);
+ if (nodeProcess != null) {
+ processes.add(nodeProcess);
+ writer.accept(success("Haskell node restarted as block producer."));
+ if (clusterInfo.isLocalMultiNodeEnabled()) {
+ localPeerService.startLocalPeersAfterCompanionHandover(clusterName, writer);
+ yanoCompanionService.waitForPostHandoverBlock(writer);
+ }
+ } else {
+ writer.accept(error("Failed to restart node as block producer."));
+ }
+ }
Process submitApiProcess = startSubmitApi(clusterInfo, clusterFolder, writer);
if (submitApiProcess == null) {
@@ -93,10 +217,12 @@ public RunStatus startCluster(ClusterInfo clusterInfo, Path clusterFolder, Consu
return new RunStatus(false, firstRun);
}
- processes.add(nodeProcess);
- if (submitApiProcess != null)
- processes.add(submitApiProcess);
+ processes.add(submitApiProcess);
+ // In companion mode, still report firstRun=true so FirstRunDone fires
+ // (topup + cost model governance proposals run against the Haskell node).
+ // The Haskell node syncs Yano's epoch history, so it starts at a later epoch
+ // and governance enactment happens faster.
return new RunStatus(true, firstRun);
} catch (IOException e) {
throw new RuntimeException(e);
@@ -204,10 +330,17 @@ public void showSubmitApiLogs(Consumer consumer) {
}
}
- private Process startNode(Path clusterFolder, ClusterInfo clusterInfo, Consumer writer) throws IOException, InterruptedException, ExecutionException, TimeoutException {
+ private Process startNode(Path clusterFolder, ClusterInfo clusterInfo, boolean asRelay, Consumer writer) throws IOException, InterruptedException, ExecutionException, TimeoutException {
String clusterFolderPath = clusterFolder.toAbsolutePath().toString();
String startScript = null;
- if (clusterInfo.isMasterNode()) {
+ if (asRelay) {
+ // Companion mode: start as relay to sync from Yano, not as block producer
+ // Create relay script on the fly (node.sh minus pool key args)
+ Path nodeDir = clusterFolder.resolve(ClusterConfig.NODE_FOLDER_PREFIX);
+ createRelayScript(nodeDir);
+ startScript = ClusterConfig.NODE_RELAY_SCRIPT;
+ writer.accept(info("Starting Haskell node as relay (syncing from Yano)..."));
+ } else if (clusterInfo.isMasterNode()) {
startScript = ClusterConfig.NODE_FOLDER_PREFIX;
} else if (clusterInfo.isBlockProducer()) {
startScript = ClusterConfig.NODE_BP_SCRIPT;
@@ -322,6 +455,81 @@ public void saveClusterInfo(Path clusterFolder, ClusterInfo clusterInfo) throws
objectMapper.writer(new DefaultPrettyPrinter()).writeValue(new File(clusterInfoPath), clusterInfo);
}
+ /**
+ * Create a relay startup script (no block producer keys) from the existing node.sh.
+ * This removes --shelley-kes-key, --shelley-vrf-key, --shelley-operational-certificate,
+ * --byron-delegation-certificate, and --byron-signing-key flags.
+ */
+ private void createRelayScript(Path nodeDir) throws IOException {
+ Path nodeScript = nodeDir.resolve("node.sh");
+ Path relayScript = nodeDir.resolve(ClusterConfig.NODE_RELAY_SCRIPT + ".sh");
+
+ if (!nodeScript.toFile().exists()) return;
+
+ String content = Files.readString(nodeScript);
+ // Remove block producer key arguments
+ content = content.replaceAll("--shelley-kes-key\\s+[^\\\\\\n]+\\\\?\\s*\n?", "");
+ content = content.replaceAll("--shelley-vrf-key\\s+[^\\\\\\n]+\\\\?\\s*\n?", "");
+ content = content.replaceAll("--shelley-operational-certificate\\s+[^\\\\\\n]+\\\\?\\s*\n?", "");
+ content = content.replaceAll("--byron-delegation-certificate\\s+[^\\\\\\n]+\\\\?\\s*\n?", "");
+ content = content.replaceAll("--byron-signing-key\\s+[^\\\\\\n]+\\\\?\\s*\n?", "");
+ // Clean up any double blank lines
+ content = content.replaceAll("\n{3,}", "\n");
+
+ Files.writeString(relayScript, content);
+ relayScript.toFile().setExecutable(true);
+ }
+
+ //Not used currently
+ /**
+ * Restart the Haskell relay node process after a Yano rollback.
+ * The chain-sync protocol stalls on deep rollbacks, so we kill the relay,
+ * delete the stale socket, and start a fresh relay that re-syncs from Yano's new tip.
+ */
+ public void restartRelayNode(ClusterInfo clusterInfo, Path clusterFolder, Consumer writer) throws IOException, InterruptedException, ExecutionException, TimeoutException {
+ writer.accept(info("Restarting Haskell relay to re-sync after rollback..."));
+
+ // Find and kill the node process (first in the list, identified by NODE_PROCESS_NAME pid file)
+ Process oldNodeProcess = null;
+ for (Process p : processes) {
+ if (p != null && p.isAlive()) {
+ // Check if this is the node process (not submit-api)
+ String cmdLine = p.info().commandLine().orElse("");
+ if (cmdLine.contains("cardano-node")) {
+ oldNodeProcess = p;
+ break;
+ }
+ }
+ }
+
+ if (oldNodeProcess != null) {
+ oldNodeProcess.descendants().forEach(ProcessHandle::destroyForcibly);
+ oldNodeProcess.destroyForcibly();
+ oldNodeProcess.waitFor(15, TimeUnit.SECONDS);
+ processes.remove(oldNodeProcess);
+ }
+
+ // Delete relay's DB and socket so it syncs fresh from Yano's new chain.
+ // The old DB has blocks from the pre-rollback fork that conflict with Yano's new chain.
+ Path nodeDir = clusterFolder.resolve(ClusterConfig.NODE_FOLDER_PREFIX);
+ Path dbPath = nodeDir.resolve("db");
+ if (dbPath.toFile().exists()) {
+ FileUtils.deleteDirectory(dbPath.toFile());
+ writer.accept(info("Cleared relay DB for fresh sync."));
+ }
+ Path socketPath = nodeDir.resolve("node.sock");
+ Files.deleteIfExists(socketPath);
+
+ // Start a fresh relay
+ Process nodeProcess = startNode(clusterFolder, clusterInfo, true, writer);
+ if (nodeProcess != null) {
+ processes.add(nodeProcess);
+ writer.accept(success("Haskell relay restarted."));
+ } else {
+ writer.accept(error("Failed to restart Haskell relay."));
+ }
+ }
+
public boolean checkIfFirstRun(Path clusterFolder) {
String node1Folder = ClusterConfig.NODE_FOLDER_PREFIX;
Path db = clusterFolder.resolve(node1Folder).resolve("db");
@@ -339,6 +547,7 @@ public boolean isClusterRunning() {
}
}
}
- return false;
+ // In yano-only mode, the cluster is running if Yano is running
+ return yanoService.isRunning();
}
}
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/NodeMode.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/NodeMode.java
new file mode 100644
index 00000000..2e1f3ecc
--- /dev/null
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/NodeMode.java
@@ -0,0 +1,31 @@
+package com.bloxbean.cardano.yacicli.localcluster;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+public enum NodeMode {
+ HASKELL_ONLY("haskell-only"),
+ COMPANION("companion"),
+ YANO_ONLY("yano-only"),
+ YANO_PRIMARY("yano-primary");
+
+ private final String value;
+
+ NodeMode(String value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public String getValue() {
+ return value;
+ }
+
+ @JsonCreator
+ public static NodeMode fromValue(String value) {
+ if (value == null) return HASKELL_ONLY;
+ for (NodeMode mode : values()) {
+ if (mode.value.equals(value)) return mode;
+ }
+ return HASKELL_ONLY;
+ }
+}
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/EpochController.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/EpochController.java
index 3c74bd23..1a062394 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/EpochController.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/EpochController.java
@@ -7,8 +7,11 @@
import com.bloxbean.cardano.yaci.core.protocol.localstate.queries.EpochNoQueryResult;
import com.bloxbean.cardano.yaci.helper.LocalClientProvider;
import com.bloxbean.cardano.yaci.helper.LocalStateQueryClient;
+import com.bloxbean.cardano.yacicli.localcluster.ClusterInfoService;
+import com.bloxbean.cardano.yacicli.localcluster.NodeMode;
import com.bloxbean.cardano.yacicli.localcluster.common.LocalClientProviderHelper;
import com.bloxbean.cardano.yacicli.localcluster.service.LocalProtocolParamSupplier;
+import com.bloxbean.cardano.yacicli.localcluster.service.YanoHttpNodeService;
import com.bloxbean.cardano.yacicli.common.CommandContext;
import com.bloxbean.cardano.yacicli.localcluster.ClusterConfig;
import io.swagger.v3.oas.annotations.Operation;
@@ -27,15 +30,38 @@
public class EpochController {
private LocalClientProviderHelper localQueryClientUtil;
+ private YanoHttpNodeService yanoHttpNodeService;
+ private ClusterInfoService clusterInfoService;
- public EpochController(LocalClientProviderHelper localQueryClientUtil) {
+ public EpochController(LocalClientProviderHelper localQueryClientUtil,
+ YanoHttpNodeService yanoHttpNodeService,
+ ClusterInfoService clusterInfoService) {
this.localQueryClientUtil = localQueryClientUtil;
+ this.yanoHttpNodeService = yanoHttpNodeService;
+ this.clusterInfoService = clusterInfoService;
+ }
+
+ private boolean isYanoOnlyMode() {
+ try {
+ String clusterName = CommandContext.INSTANCE.getProperty(ClusterConfig.CLUSTER_NAME);
+ var info = clusterInfoService.getClusterInfo(clusterName);
+ return NodeMode.YANO_ONLY == info.getNodeMode();
+ } catch (Exception e) {
+ return false;
+ }
}
@Operation(summary = "Retrieve the latest epoch.")
@GetMapping("latest")
public EpochContent getLatestEpoch() {
String clusterName = CommandContext.INSTANCE.getProperty(ClusterConfig.CLUSTER_NAME);
+
+ if (isYanoOnlyMode()) {
+ EpochContent result = yanoHttpNodeService.getLatestEpoch(clusterName);
+ if (result != null) return result;
+ throw new RuntimeException("Failed to get latest epoch from Yano");
+ }
+
Era era = CommandContext.INSTANCE.getEra();
LocalClientProvider localClientProvider = null;
@@ -59,6 +85,13 @@ public EpochContent getLatestEpoch() {
@GetMapping("parameters")
ProtocolParams getProtocolParameters() {
String clusterName = CommandContext.INSTANCE.getProperty(ClusterConfig.CLUSTER_NAME);
+
+ if (isYanoOnlyMode()) {
+ ProtocolParams result = yanoHttpNodeService.getProtocolParams(clusterName);
+ if (result != null) return result;
+ throw new RuntimeException("Failed to get protocol parameters from Yano");
+ }
+
Era era = CommandContext.INSTANCE.getEra();
LocalClientProvider localClientProvider = null;
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/RollbackController.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/RollbackController.java
index cfee0f78..b2aafc8f 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/RollbackController.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/RollbackController.java
@@ -51,6 +51,27 @@ public String rollbackToDBSnapshot() {
return sb.toString();
}
+ @PostMapping("/rollback")
+ @Operation(summary = "Rollback N blocks (yano-primary mode only)",
+ description = "Rollback the chain by the specified number of blocks via Yano's rollback API. " +
+ "Only available in yano-primary mode. Number of blocks must not exceed securityParam.")
+ public ResponseEntity rollback(@RequestBody RollbackRequest request) {
+ StringBuilder sb = new StringBuilder();
+ boolean status = rollbackService.rollback(request.blocks(), msg -> sb.append(msg));
+
+ writeLn(sb.toString());
+ if (status) {
+ return ResponseEntity.ok(sb.toString());
+ } else {
+ return ResponseEntity.badRequest().body(sb.toString());
+ }
+ }
+
+ record RollbackRequest(
+ @Schema(description = "Number of blocks to rollback")
+ long blocks
+ ) {}
+
@PostMapping("/create-forks")
@Operation(summary = "Create forks for rollback",
description = "Create forks for rollback. This will detach the main node from the peer nodes and create" +
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/TransactionController.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/TransactionController.java
index a51f6aad..f0901d73 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/TransactionController.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/TransactionController.java
@@ -2,11 +2,16 @@
import com.bloxbean.cardano.client.backend.model.TransactionContent;
import com.bloxbean.cardano.yaci.core.protocol.chainsync.messages.Point;
+import com.bloxbean.cardano.yacicli.localcluster.ClusterConfig;
+import com.bloxbean.cardano.yacicli.localcluster.ClusterInfoService;
+import com.bloxbean.cardano.yacicli.localcluster.NodeMode;
import com.bloxbean.cardano.yacicli.localcluster.service.ClusterUtilService;
+import com.bloxbean.cardano.yacicli.common.CommandContext;
import com.bloxbean.cardano.yacicli.common.Tuple;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
@@ -18,11 +23,26 @@
@RestController
@RequestMapping(path = "/local-cluster/api")
@Tag(name = "Transaction API", description = "Handles submission of transactions and simulate transaction lookups.")
+@Slf4j
public class TransactionController {
private final ClusterUtilService clusterUtilService;
+ private final ClusterInfoService clusterInfoService;
private RestTemplate restTemplate = new RestTemplate();
- private final String SUBMIT_API_URL = "http://localhost:8090/api/submit/tx";
+ private static final String DEFAULT_SUBMIT_API_URL = "http://localhost:8090/api/submit/tx";
+
+ private String getSubmitUrl() {
+ try {
+ String clusterName = CommandContext.INSTANCE.getProperty(ClusterConfig.CLUSTER_NAME);
+ var info = clusterInfoService.getClusterInfo(clusterName);
+ if (NodeMode.YANO_ONLY == info.getNodeMode()) {
+ return "http://localhost:" + info.getYanoHttpPort() + "/api/v1/tx/submit";
+ }
+ } catch (Exception e) {
+ log.debug("Error resolving submit URL, using default", e);
+ }
+ return DEFAULT_SUBMIT_API_URL;
+ }
@Operation(summary = "Submit Transaction", description = "Submit a transaction in CBOR format to the cluster.",
@@ -39,7 +59,7 @@ ResponseEntity submit(@RequestBody byte[] cborTx) {
HttpEntity entity = new HttpEntity<>(cborTx, headers);
try {
ResponseEntity responseEntity = restTemplate
- .exchange(SUBMIT_API_URL, HttpMethod.POST, entity, String.class);
+ .exchange(getSubmitUrl(), HttpMethod.POST, entity, String.class);
return responseEntity;
} catch (Exception e) {
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/service/TestTransactionService.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/service/TestTransactionService.java
index 1445ee6a..66b32a0c 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/service/TestTransactionService.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/api/service/TestTransactionService.java
@@ -13,6 +13,7 @@
import com.bloxbean.cardano.client.util.HexUtil;
import com.bloxbean.cardano.yacicli.common.CommandContext;
import com.bloxbean.cardano.yacicli.localcluster.ClusterConfig;
+import com.bloxbean.cardano.yacicli.localcluster.NodeMode;
import com.bloxbean.cardano.yacicli.localcluster.ClusterService;
import com.bloxbean.cardano.yacicli.localcluster.service.DefaultAddressService;
import lombok.RequiredArgsConstructor;
@@ -136,9 +137,12 @@ private Optional getBackendService() {
return Optional.empty();
}
- var yaciStorePort = clusterInfo.getYaciStorePort();
-
- String backendUrl = "http://localhost:" + yaciStorePort + "/api/v1/";
+ String backendUrl;
+ if (NodeMode.YANO_ONLY == clusterInfo.getNodeMode()) {
+ backendUrl = "http://localhost:" + clusterInfo.getYanoHttpPort() + "/api/v1/";
+ } else {
+ backendUrl = "http://localhost:" + clusterInfo.getYaciStorePort() + "/api/v1/";
+ }
return Optional.of(new BFBackendService(backendUrl, "dummy_key"));
} catch (Exception e) {
log.error("Error getting backend service", e);
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/commands/RollbackCommands.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/commands/RollbackCommands.java
index 12259176..9507d643 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/commands/RollbackCommands.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/commands/RollbackCommands.java
@@ -32,6 +32,13 @@ public void rollbackToLastDBSnapshot() {
rollbackService.rollbackToLastDBSnapshot(msg -> writeLn(msg));
}
+ @ShellMethod(value = "Rollback N blocks (yano-primary mode only)", key = "rollback")
+ @ShellMethodAvailability("localClusterCmdAvailability")
+ public void rollback(
+ @ShellOption(value = {"--blocks"}, help = "Number of blocks to rollback") long blocks) {
+ rollbackService.rollback(blocks, msg -> writeLn(msg));
+ }
+
@ShellMethod(value = "Create forks for rollback", key = "create-forks")
@ShellMethodAvailability("localClusterCmdAvailability")
public void createForks(
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/commands/TxnCommands.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/commands/TxnCommands.java
index ac3f0667..ee0c473e 100644
--- a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/commands/TxnCommands.java
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/commands/TxnCommands.java
@@ -31,8 +31,8 @@ public class TxnCommands {
@ShellMethod(value = "Topup account", key = "topup")
@ShellMethodAvailability("localClusterCmdAvailability")
- public void mintToken(@ShellOption(value = {"-a", "--address"}, help = "Receiver address") String address,
- @ShellOption(value = {"-v", "--value"}, help = "Ada value") double adaValue) {
+ public void topup(@ShellOption(value = {"-a", "--address"}, help = "Receiver address") String address,
+ @ShellOption(value = {"-v", "--value"}, help = "Ada value") double adaValue) {
String clusterName = CommandContext.INSTANCE.getProperty(CLUSTER_NAME);
Era era = CommandContext.INSTANCE.getEra();
@@ -82,9 +82,9 @@ public void getUtxos(@ShellOption(value = {"-a", "--address"}, help = "Address")
@ShellMethod(value = "Mint tokens using faucet account with default policy", key = "mint")
@ShellMethodAvailability("localClusterCmdAvailability")
- public void mintToken(@ShellOption(value = {"-n", "--asset-name"}, help = "Asset Name") String assetName,
- @ShellOption(value = {"-q", "--quantity"}, help = "Quantity") BigInteger quantity,
- @ShellOption(value = {"-r", "--receiver"}, help = "Reciever Address") String receiver
+ public void topup(@ShellOption(value = {"-n", "--asset-name"}, help = "Asset Name") String assetName,
+ @ShellOption(value = {"-q", "--quantity"}, help = "Quantity") BigInteger quantity,
+ @ShellOption(value = {"-r", "--receiver"}, help = "Reciever Address") String receiver
) {
String clusterName = CommandContext.INSTANCE.getProperty(CLUSTER_NAME);
Era era = CommandContext.INSTANCE.getEra();
diff --git a/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/common/GenesisUtil.java b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/common/GenesisUtil.java
new file mode 100644
index 00000000..2516a10e
--- /dev/null
+++ b/applications/cli/src/main/java/com/bloxbean/cardano/yacicli/localcluster/common/GenesisUtil.java
@@ -0,0 +1,55 @@
+package com.bloxbean.cardano.yacicli.localcluster.common;
+
+import com.bloxbean.cardano.client.crypto.SecretKey;
+import com.bloxbean.cardano.client.crypto.VerificationKey;
+import com.bloxbean.cardano.yacicli.common.Tuple;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Shared utility methods for genesis UTXO keys and cost model loading,
+ * used by both LocalNodeService and YanoGovernanceService.
+ */
+public class GenesisUtil {
+ private static final String UTXO_KEYS_FOLDER = "utxo-keys";
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ public static List> loadUtxoKeys(Path clusterFolder) throws IOException {
+ List> keys = new ArrayList<>();
+ Path utxoFolder = clusterFolder.resolve(UTXO_KEYS_FOLDER);
+
+ for (int i = 1; i <= 3; i++) {
+ Path skeyPath = utxoFolder.resolve("utxo" + i + ".skey");
+ SecretKey skey = objectMapper.readValue(skeyPath.toFile(), SecretKey.class);
+
+ Path vkeyPath = utxoFolder.resolve("utxo" + i + ".vkey");
+ VerificationKey vkey = objectMapper.readValue(vkeyPath.toFile(), VerificationKey.class);
+ keys.add(new Tuple<>(vkey, skey));
+ }
+ return keys;
+ }
+
+ public static Map loadCostModels(Path costModelsFile) throws IOException {
+ Map> raw = objectMapper.readValue(costModelsFile.toFile(),
+ new TypeReference