From ca3881d61e9d7b9b222f0dfa8c159858650f5445 Mon Sep 17 00:00:00 2001 From: matiwinnetou Date: Tue, 29 Apr 2025 14:24:43 +0200 Subject: [PATCH 1/6] feat: ubuntu 24.04 upgrade. (#419) Co-authored-by: Mateusz Czeladka --- api/Dockerfile | 2 +- docker/Dockerfile | 8 ++++---- docker/dockerfiles/mithril/Dockerfile | 6 +++--- docker/dockerfiles/node/Dockerfile | 4 ++-- yaci-indexer/Dockerfile | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/api/Dockerfile b/api/Dockerfile index 3a095b612..bcfd28631 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 AS build-common +FROM ubuntu:24.04 AS build-common WORKDIR /build RUN apt update --fix-missing \ diff --git a/docker/Dockerfile b/docker/Dockerfile index 0b1cbaec4..c93f0101c 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 AS cardano-builder +FROM ubuntu:24.04 AS cardano-builder SHELL ["/bin/bash", "-c"] @@ -40,7 +40,7 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y \ && export PATH="$HOME/.cargo/bin:$PATH" \ && apt update --fix-missing \ && apt install -y --no-install-recommends \ - build-essential m4 libssl-dev docker jq git \ + build-essential m4 libssl-dev docker.io jq git \ && rustup update stable \ && apt-get clean @@ -144,7 +144,7 @@ RUN mkdir -p /root/.local/bin \ # Compile java applications -FROM ubuntu:22.04 AS java-builder +FROM ubuntu:24.04 AS java-builder WORKDIR /root/app @@ -162,7 +162,7 @@ COPY ./.git /root/app/.git RUN --mount=type=cache,target=/root/.m2 mvn -U clean package -DskipTests # Main -FROM ubuntu:22.04 +FROM ubuntu:24.04 WORKDIR / diff --git a/docker/dockerfiles/mithril/Dockerfile b/docker/dockerfiles/mithril/Dockerfile index bc6a9e4c2..8a1ce943c 100644 --- a/docker/dockerfiles/mithril/Dockerfile +++ b/docker/dockerfiles/mithril/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 AS cardano-builder +FROM ubuntu:24.04 AS cardano-builder SHELL ["/bin/bash", "-c"] @@ -16,7 +16,7 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y \ && export PATH="$HOME/.cargo/bin:$PATH" \ && apt update --fix-missing \ && apt install -y --no-install-recommends \ - build-essential m4 libssl-dev docker jq git pkg-config \ + build-essential m4 libssl-dev docker.io jq git pkg-config \ && apt-get clean RUN git clone https://github.com/input-output-hk/mithril.git \ @@ -28,7 +28,7 @@ RUN git clone https://github.com/input-output-hk/mithril.git \ && mkdir -p /root/.local/bin \ && cp mithril-client /root/.local/bin/ -FROM ubuntu:22.04 AS mithril-runner +FROM ubuntu:24.04 AS mithril-runner COPY --from=cardano-builder /root/.local/bin/mithril-client /usr/local/bin RUN apt update --fix-missing \ diff --git a/docker/dockerfiles/node/Dockerfile b/docker/dockerfiles/node/Dockerfile index 764e641e3..b554d87d4 100644 --- a/docker/dockerfiles/node/Dockerfile +++ b/docker/dockerfiles/node/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 AS cardano-builder +FROM ubuntu:24.04 AS cardano-builder WORKDIR /root/src @@ -121,5 +121,5 @@ RUN mkdir -p /root/.local/bin \ && cp -p "$(./scripts/bin-path.sh cardano-submit-api)" /root/.local/bin/ -FROM ubuntu:22.04 AS node-runner +FROM ubuntu:24.04 AS node-runner COPY --from=cardano-builder /root/.local/bin/cardano-* /usr/local/bin/ diff --git a/yaci-indexer/Dockerfile b/yaci-indexer/Dockerfile index 504b98e52..fb3e65dd0 100644 --- a/yaci-indexer/Dockerfile +++ b/yaci-indexer/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 AS build-common +FROM ubuntu:24.04 AS build-common WORKDIR /build RUN apt update --fix-missing \ From 030f74d0f9ed5a3d658559a7e57e7e305e5061d3 Mon Sep 17 00:00:00 2001 From: matiwinnetou Date: Tue, 29 Apr 2025 15:02:31 +0200 Subject: [PATCH 2/6] chore: spring boot upgrade for yaci-indexer (#425) Co-authored-by: Mateusz Czeladka --- pom.xml | 2 +- yaci-indexer/pom.xml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8ef5a225b..5645ee421 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ 3.2.5 0.8.11 1.3.0 - 1.18.30 + 1.18.38 2.2.8 2.20.0 0.6.4 diff --git a/yaci-indexer/pom.xml b/yaci-indexer/pom.xml index b14b83a94..c006221ba 100644 --- a/yaci-indexer/pom.xml +++ b/yaci-indexer/pom.xml @@ -2,10 +2,11 @@ 4.0.0 + org.springframework.boot spring-boot-starter-parent - 3.2.4 + 3.3.10 From 2043a47bc4f29ff5c8d6fb26cf1fa26b914ef126 Mon Sep 17 00:00:00 2001 From: VladislavKudrin Date: Tue, 29 Apr 2025 16:32:06 +0200 Subject: [PATCH 3/6] feat: docker compose build from source (#420) * feat: postgres dockerfile * feat: build node from source * feat: build postgres from source * feat: adjust integration tests --- .env.IntegrationTest | 5 +- .env.docker-compose | 5 +- docker-compose-indexer.yaml | 54 ++++---- docker-compose-node.yaml | 28 ++--- docker/dockerfiles/node/Dockerfile | 15 ++- docker/dockerfiles/node/entrypoint.sh | 28 +++++ docker/dockerfiles/postgres/Dockerfile | 40 ++++++ docker/dockerfiles/postgres/entrypoint.sh | 143 ++++++++++++++++++++++ 8 files changed, 265 insertions(+), 53 deletions(-) create mode 100644 docker/dockerfiles/node/entrypoint.sh create mode 100644 docker/dockerfiles/postgres/Dockerfile create mode 100644 docker/dockerfiles/postgres/entrypoint.sh diff --git a/.env.IntegrationTest b/.env.IntegrationTest index 8cc98e009..de234a137 100644 --- a/.env.IntegrationTest +++ b/.env.IntegrationTest @@ -4,8 +4,7 @@ NETWORK=devkit PROTOCOL_MAGIC=42 ## Postgres image -DB_IMAGE_NAME=postgres -DB_IMAGE_TAG=latest +PG_VERSION_TAG=REL_14_11 ## Yaci image YACI_VERSION=0.10.5 @@ -138,4 +137,4 @@ DB_POSTGRES_MAX_PARALLEL_WORKERS=4 DB_POSTGRES_SEQ_PAGE_COST=1.0 DB_POSTGRES_JIT=off DB_POSTGRES_BGWRITER_LRU_MAXPAGES=50 -DB_POSTGRES_BGWRITER_DELAY=500ms \ No newline at end of file +DB_POSTGRES_BGWRITER_DELAY=500ms diff --git a/.env.docker-compose b/.env.docker-compose index c17d06a0c..9e267bd2a 100644 --- a/.env.docker-compose +++ b/.env.docker-compose @@ -7,8 +7,7 @@ PROTOCOL_MAGIC=764824073 # mainnet 764824073, preprod 1, preview 2, sanchonet 4, devkit 42 ## Postgres image -DB_IMAGE_NAME=postgres -DB_IMAGE_TAG=14.11-bullseye +PG_VERSION_TAG=REL_14_11 ## Postgres variables DB_NAME=rosetta-java @@ -26,7 +25,7 @@ CARDANO_NODE_HOST=cardano-node CARDANO_NODE_PORT=3001 # Uncomment if you are using local cardano node CARDANO_NODE_VERSION=10.2.1 -CARDANO_NODE_SUBMIT_HOST=cardano-submit-api +CARDANO_NODE_SUBMIT_HOST=$CARDANO_NODE_HOST NODE_SUBMIT_API_PORT=8090 CARDANO_NODE_DIR=/node CARDANO_NODE_SOCKET_PATH=${CARDANO_NODE_DIR}/node.socket diff --git a/docker-compose-indexer.yaml b/docker-compose-indexer.yaml index 4cf59eab6..ec52e7c7e 100644 --- a/docker-compose-indexer.yaml +++ b/docker-compose-indexer.yaml @@ -42,37 +42,39 @@ services: condition: service_healthy db: - image: ${DB_IMAGE_NAME}:${DB_IMAGE_TAG} + image: postgres:${PG_VERSION_TAG} + build: + context: ./ + dockerfile: ./docker/dockerfiles/postgres/Dockerfile shm_size: 4g ports: - ${DB_PORT}:${DB_PORT} - command: [ - # "postgres", - "-p", "${DB_PORT}", - "-c", "max_connections=${DB_POSTGRES_MAX_CONNECTIONS}", - "-c", "shared_buffers=${DB_POSTGRES_SHARED_BUFFERS}", - "-c", "effective_cache_size=${DB_POSTGRES_EFFECTIVE_CACHE_SIZE}", - "-c", "work_mem=${DB_POSTGRES_WORK_MEM}", - "-c", "maintenance_work_mem=${DB_POSTGRES_MAINTENANCE_WORK_MEM}", - "-c", "wal_buffers=${DB_POSTGRES_WAL_BUFFERS}", - "-c", "checkpoint_completion_target=${DB_POSTGRES_CHECKPOINT_COMPLETION_TARGET}", - "-c", "random_page_cost=${DB_POSTGRES_RANDOM_PAGE_COST}", + environment: + DB_SECRET: ${DB_SECRET} + DB_USER: ${DB_USER} + DB_NAME: ${DB_NAME} + NETWORK: ${NETWORK} + PGPASSWORD: postgres + + DB_POSTGRES_MAX_CONNECTIONS: ${DB_POSTGRES_MAX_CONNECTIONS} + DB_POSTGRES_SHARED_BUFFERS: ${DB_POSTGRES_SHARED_BUFFERS} + DB_POSTGRES_EFFECTIVE_CACHE_SIZE: ${DB_POSTGRES_EFFECTIVE_CACHE_SIZE} + DB_POSTGRES_WORK_MEM: ${DB_POSTGRES_WORK_MEM} + DB_POSTGRES_MAINTENANCE_WORK_MEM: ${DB_POSTGRES_MAINTENANCE_WORK_MEM} + DB_POSTGRES_WAL_BUFFERS: ${DB_POSTGRES_WAL_BUFFERS} + DB_POSTGRES_CHECKPOINT_COMPLETION_TARGET: ${DB_POSTGRES_CHECKPOINT_COMPLETION_TARGET} + DB_POSTGRES_RANDOM_PAGE_COST: ${DB_POSTGRES_RANDOM_PAGE_COST} # Additional settings for advanced PostgreSQL tuning - "-c", "effective_io_concurrency=${DB_POSTGRES_EFFECTIVE_IO_CONCURRENCY}", - "-c", "parallel_tuple_cost=${DB_POSTGRES_PARALLEL_TUPLE_COST}", - "-c", "parallel_setup_cost=${DB_POSTGRES_PARALLEL_SETUP_COST}", - "-c", "max_parallel_workers_per_gather=${DB_POSTGRES_MAX_PARALLEL_WORKERS_PER_GATHER}", - "-c", "max_parallel_workers=${DB_POSTGRES_MAX_PARALLEL_WORKERS}", - "-c", "seq_page_cost=${DB_POSTGRES_SEQ_PAGE_COST}", - "-c", "jit=${DB_POSTGRES_JIT}", - "-c", "bgwriter_lru_maxpages=${DB_POSTGRES_BGWRITER_LRU_MAXPAGES}", - "-c", "bgwriter_delay=${DB_POSTGRES_BGWRITER_DELAY}" - ] - environment: - POSTGRES_PASSWORD: ${DB_SECRET} - POSTGRES_USER: ${DB_USER} - POSTGRES_DB: ${DB_NAME} + DB_POSTGRES_EFFECTIVE_IO_CONCURRENCY: ${DB_POSTGRES_EFFECTIVE_IO_CONCURRENCY} + DB_POSTGRES_PARALLEL_TUPLE_COST: ${DB_POSTGRES_PARALLEL_TUPLE_COST} + DB_POSTGRES_PARALLEL_SETUP_COST: ${DB_POSTGRES_PARALLEL_SETUP_COST} + DB_POSTGRES_MAX_PARALLEL_WORKERS_PER_GATHER: ${DB_POSTGRES_MAX_PARALLEL_WORKERS_PER_GATHER} + DB_POSTGRES_MAX_PARALLEL_WORKERS: ${DB_POSTGRES_MAX_PARALLEL_WORKERS} + DB_POSTGRES_SEQ_PAGE_COST: ${DB_POSTGRES_SEQ_PAGE_COST} + DB_POSTGRES_JIT: ${DB_POSTGRES_JIT} + DB_POSTGRES_BGWRITER_LRU_MAXPAGES: ${DB_POSTGRES_BGWRITER_LRU_MAXPAGES} + DB_POSTGRES_BGWRITER_DELAY: ${DB_POSTGRES_BGWRITER_DELAY} restart: on-failure volumes: - ${DB_PATH}:/var/lib/postgresql/data diff --git a/docker-compose-node.yaml b/docker-compose-node.yaml index 56029f002..9a343b28b 100644 --- a/docker-compose-node.yaml +++ b/docker-compose-node.yaml @@ -14,8 +14,17 @@ services: cardano-node: image: ghcr.io/intersectmbo/cardano-node:${CARDANO_NODE_VERSION} + build: + context: ./ + dockerfile: ./docker/dockerfiles/node/Dockerfile + args: + CARDANO_NODE_VERSION: ${CARDANO_NODE_VERSION} environment: - NETWORK=${NETWORK} + - PROTOCOL_MAGIC=${PROTOCOL_MAGIC} + - CARDANO_NODE_SOCKET_PATH=${CARDANO_NODE_SOCKET_PATH} + - CARDANO_NODE_PORT=${CARDANO_NODE_PORT} + - NODE_SUBMIT_API_PORT=${NODE_SUBMIT_API_PORT} volumes: - ${CARDANO_NODE_DIR}:/node/ - ${CARDANO_NODE_DB}:/node/db @@ -23,27 +32,10 @@ services: restart: unless-stopped ports: - ${CARDANO_NODE_PORT}:${CARDANO_NODE_PORT} - entrypoint: cardano-node run --database-path /node/db --port ${CARDANO_NODE_PORT} --socket-path /node/node.socket --topology /config/topology.json --config /config/config.json + - ${NODE_SUBMIT_API_PORT}:${NODE_SUBMIT_API_PORT} depends_on: mithril: condition: service_completed_successfully - cardano-submit-api: - image: ghcr.io/intersectmbo/cardano-submit-api:${CARDANO_NODE_VERSION} - environment: - - NETWORK=${NETWORK} - depends_on: - - cardano-node - volumes: - - ${CARDANO_NODE_DIR}:/node-ipc - ports: - - ${NODE_SUBMIT_API_PORT}:8090 - restart: on-failure - logging: - driver: "json-file" - options: - max-size: "200k" - max-file: "10" - networks: default: diff --git a/docker/dockerfiles/node/Dockerfile b/docker/dockerfiles/node/Dockerfile index b554d87d4..3407f183b 100644 --- a/docker/dockerfiles/node/Dockerfile +++ b/docker/dockerfiles/node/Dockerfile @@ -45,9 +45,6 @@ RUN export IOHKNIX_VERSION=$(curl https://raw.githubusercontent.com/IntersectMBO && make check \ && make install -ENV LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH -ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH - # Install libsodium RUN apt install -y --no-install-recommends libsodium-dev \ && apt-get clean @@ -122,4 +119,16 @@ RUN mkdir -p /root/.local/bin \ FROM ubuntu:24.04 AS node-runner +COPY --from=cardano-builder /usr/local/lib /usr/local/lib COPY --from=cardano-builder /root/.local/bin/cardano-* /usr/local/bin/ +COPY --from=cardano-builder /root/src/cardano-node/cardano-submit-api/config/tx-submit-mainnet-config.yaml /cardano-submit-api-config/cardano-submit-api.yaml + +ENV LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH +ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH + +RUN mkdir /logs + +COPY ./docker/dockerfiles/node/entrypoint.sh /sbin/entrypoint.sh +RUN chmod +x /sbin/entrypoint.sh + +ENTRYPOINT ["/sbin/entrypoint.sh"] diff --git a/docker/dockerfiles/node/entrypoint.sh b/docker/dockerfiles/node/entrypoint.sh new file mode 100644 index 000000000..6325cab27 --- /dev/null +++ b/docker/dockerfiles/node/entrypoint.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +if [ "$NETWORK" == "mainnet" ]; then + NETWORK_STR="--mainnet" +else + NETWORK_STR="--testnet-magic $PROTOCOL_MAGIC" +fi + +function clean_up() { + # Killing all processes before exiting + kill -2 "$CARDANO_NODE_PID" "$CARDANO_SUBMIT_PID" + wait $CARDANO_NODE_PID + exit +} + +trap clean_up SIGHUP SIGINT SIGTERM + +echo "Starting Cardano node..." + +cardano-node run --socket-path "$CARDANO_NODE_SOCKET_PATH" --port $CARDANO_NODE_PORT --database-path /node/db --config /config/config.json --topology /config/topology.json > /logs/node.log & +CARDANO_NODE_PID=$! +sleep 2 + +echo "Starting Cardano submit api..." +cardano-submit-api --listen-address 0.0.0.0 --socket-path "$CARDANO_NODE_SOCKET_PATH" --port $NODE_SUBMIT_API_PORT $NETWORK_STR --config /cardano-submit-api-config/cardano-submit-api.yaml > /logs/submit-api.log & +CARDANO_SUBMIT_PID=$! + +wait -n $CARDANO_NODE_PID $CARDANO_SUBMIT_PID diff --git a/docker/dockerfiles/postgres/Dockerfile b/docker/dockerfiles/postgres/Dockerfile new file mode 100644 index 000000000..938941da6 --- /dev/null +++ b/docker/dockerfiles/postgres/Dockerfile @@ -0,0 +1,40 @@ +FROM ubuntu:22.04 + +RUN apt update && apt install -y \ + build-essential \ + libreadline-dev \ + zlib1g-dev \ + flex \ + bison \ + wget \ + git \ + ca-certificates \ + sudo \ + && apt clean + +ENV PG_VERSION_TAG=REL_14_11 +ENV PG_DATA="/var/lib/postgresql/data" +ENV PG_BIN="/usr/local/pgsql/bin" +ENV PATH="$PG_BIN:$PATH" + +WORKDIR /usr/src + +RUN git clone --branch $PG_VERSION_TAG https://github.com/postgres/postgres.git \ + && cd postgres \ + && ./configure --prefix=/usr/local/pgsql \ + && make -j$(nproc) \ + && make install + +RUN useradd -m -U -s /bin/bash postgres + +RUN mkdir -p $PG_DATA + +VOLUME ["$PG_DATA"] + +COPY ./docker/dockerfiles/postgres/entrypoint.sh /sbin/entrypoint.sh +RUN chmod +x /sbin/entrypoint.sh + +WORKDIR / + +ENTRYPOINT ["/sbin/entrypoint.sh"] + diff --git a/docker/dockerfiles/postgres/entrypoint.sh b/docker/dockerfiles/postgres/entrypoint.sh new file mode 100644 index 000000000..1ea0748a7 --- /dev/null +++ b/docker/dockerfiles/postgres/entrypoint.sh @@ -0,0 +1,143 @@ +#!/bin/bash + +database_initialization() { + if [ -z "$(ls -A "$PG_DATA")" ]; then + echo "$PGPASSWORD" > /tmp/password + echo "*:*:*:postgres:$PGPASSWORD" > /home/postgres/.pgpass + + chmod 600 /home/postgres/.pgpass + chown postgres:postgres /home/postgres/.pgpass + + sudo -u postgres "$PG_BIN/initdb" --pgdata="$PG_DATA" --auth=md5 --auth-local=md5 --auth-host=md5 --username=postgres --pwfile=/tmp/password + + rm -f /tmp/password + else + echo "Database already initialized, skipping initdb." + fi +} + +configure_postgres() { + local config_file="$PG_DATA/postgresql.conf" + + # List of parameter names and their corresponding environment variables + declare -A param_vars=( + ["max_connections"]="DB_POSTGRES_MAX_CONNECTIONS" + ["shared_buffers"]="DB_POSTGRES_SHARED_BUFFERS" + ["effective_cache_size"]="DB_POSTGRES_EFFECTIVE_CACHE_SIZE" + ["work_mem"]="DB_POSTGRES_WORK_MEM" + ["maintenance_work_mem"]="DB_POSTGRES_MAINTENANCE_WORK_MEM" + ["wal_buffers"]="DB_POSTGRES_WAL_BUFFERS" + ["checkpoint_completion_target"]="DB_POSTGRES_CHECKPOINT_COMPLETION_TARGET" + ["random_page_cost"]="DB_POSTGRES_RANDOM_PAGE_COST" + ["effective_io_concurrency"]="DB_POSTGRES_EFFECTIVE_IO_CONCURRENCY" + ["parallel_tuple_cost"]="DB_POSTGRES_PARALLEL_TUPLE_COST" + ["parallel_setup_cost"]="DB_POSTGRES_PARALLEL_SETUP_COST" + ["max_parallel_workers_per_gather"]="DB_POSTGRES_MAX_PARALLEL_WORKERS_PER_GATHER" + ["max_parallel_workers"]="DB_POSTGRES_MAX_PARALLEL_WORKERS" + ["seq_page_cost"]="DB_POSTGRES_SEQ_PAGE_COST" + ["jit"]="DB_POSTGRES_JIT" + ["bgwriter_lru_maxpages"]="DB_POSTGRES_BGWRITER_LRU_MAXPAGES" + ["bgwriter_delay"]="DB_POSTGRES_BGWRITER_DELAY" + ) + + # Check for missing required environment variables + local missing_vars=() + for param in "${!param_vars[@]}"; do + local env_var="${param_vars[$param]}" + if [ -z "${!env_var}" ]; then + missing_vars+=("$env_var") + fi + done + + # If there are missing variables, print an error and exit + if [ ${#missing_vars[@]} -gt 0 ]; then + echo "Error: The following required environment variables are missing or empty:" + for var in "${missing_vars[@]}"; do + echo " - $var" + done + echo "" + echo "Most likely, you are missing a hardware profile in your environment configuration." + echo "Make sure to pass an additional --env-file parameter when running the container." + echo "" + echo "Example Docker run command for an 'entry_level' hardware profile:" + echo "docker run --env-file ./docker/.env.dockerfile --env-file ./docker/.env.docker-profile-mid-level -p 8082:8082 --shm-size=4g -d cardanofoundation/cardano-rosetta-java:latest" + echo "" + exit 1 + fi + + # Remove all commented-out lines for the parameters we are about to update + for param in "${!param_vars[@]}"; do + sed -i "/^#$param /d" "$config_file" + done + + # Update or add parameters + for param in "${!param_vars[@]}"; do + local env_var="${param_vars[$param]}" + local value="${!env_var}" + + # Try to replace existing parameter + sed -i "s/^$param = .*/$param = $value/" "$config_file" + + # Parameter not found, append it + if ! grep -q "^$param =" "$config_file"; then + echo "$param = $value" >> "$config_file" + fi + done + + echo "host all all 0.0.0.0/0 md5" \ + >> $PG_DATA/pg_hba.conf + + echo "listen_addresses='*'" \ + >> $PG_DATA/postgresql.conf + + echo "PostgreSQL configuration updated successfully!" +} + +start_postgres() { + sudo -u postgres "$PG_BIN/postgres" -D "$PG_DATA" -c config_file="$PG_DATA/postgresql.conf" & + PG_PID=$! + + until "$PG_BIN/pg_isready" -U postgres > /dev/null; do sleep 1; done +} + +create_database_and_user() { + export DB_SCHEMA="$NETWORK" + + flag=true + while [ $(sudo -u postgres "$PG_BIN/psql" -U postgres -Atc "SELECT pg_is_in_recovery()";) == "t" ]; do + if $flag ; then + echo "Waiting for database recovery..." + flag=false + fi + sleep 1 + done + + if [[ -z $(sudo -u postgres "$PG_BIN/psql" -U postgres -Atc "SELECT 1 FROM pg_catalog.pg_user WHERE usename = '$DB_USER'";) ]]; then + echo "Creating database..." + sudo -u postgres "$PG_BIN/psql" -U postgres -c "CREATE ROLE \"$DB_USER\" with LOGIN CREATEDB PASSWORD '$DB_SECRET';" > /dev/null + fi + + if [[ -z $(sudo -u postgres "$PG_BIN/psql" -U postgres -Atc "SELECT 1 FROM pg_catalog.pg_database WHERE datname = '$DB_NAME'";) ]]; then + echo "Creating user..." + sudo -u postgres "$PG_BIN/psql" -U postgres -c "CREATE DATABASE \"$DB_NAME\";" >/dev/null + sudo -u postgres "$PG_BIN/psql" -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE \"$DB_NAME\" to \"$DB_USER\";" > /dev/null + fi +} + +chown -R postgres:postgres "$PG_DATA" +chmod -R 0700 "$PG_DATA" + +echo "Initializing Database..." +database_initialization + +echo "Configuring the Database..." +configure_postgres + +echo "Starting Postgres..." +start_postgres + +echo "Creating database and user..." +create_database_and_user + +wait "$PG_PID" + From 8072e1fafb9ceec8eb91ad2d993a547b81f8f4a1 Mon Sep 17 00:00:00 2001 From: matiwinnetou Date: Tue, 29 Apr 2025 21:20:46 +0200 Subject: [PATCH 4/6] feat: sync status in the network service response. (#429) Co-authored-by: Mateusz Czeladka --- .../api/block/model/domain/NetworkStatus.java | 3 + .../CardanoConstructionServiceImpl.java | 2 +- .../service/ConstructionApiServiceImpl.java | 4 +- .../network/controller/NetworkApiImpl.java | 11 +- .../api/network/mapper/NetworkMapper.java | 1 + .../network/service/GenesisDataProvider.java | 7 + .../service/GenesisDataProviderImpl.java | 54 +++++++ .../api/network/service/NetworkService.java | 2 +- .../network/service/NetworkServiceImpl.java | 136 ++++++++---------- .../api/network/service/SlotRangeChecker.java | 21 +++ .../common/time/OfflineSlotService.java | 6 +- .../common/time/OfflineSlotServiceImpl.java | 31 ++-- .../config/CardanoConvertersConfig.java | 31 ++-- .../service/NetworkServiceImplTest.java | 2 + .../network/service/SlotRangeCheckerTest.java | 35 +++++ .../time/OfflineSlotServiceImplTest.java | 48 +++++-- .../service/AccountServiceImpl.java | 20 +-- .../TransactionScriptSizeCalculatorImpl.java | 10 +- .../TransactionSizeCalculatorImpl.java | 5 +- .../txsize/CustomTransactionSizeStore.java | 18 +-- .../txsize/model/TransactionSizeEntity.java | 1 + .../CustomTransactionSizeStoreTest.java | 16 ++- 22 files changed, 322 insertions(+), 142 deletions(-) create mode 100644 api/src/main/java/org/cardanofoundation/rosetta/api/network/service/GenesisDataProvider.java create mode 100644 api/src/main/java/org/cardanofoundation/rosetta/api/network/service/GenesisDataProviderImpl.java create mode 100644 api/src/main/java/org/cardanofoundation/rosetta/api/network/service/SlotRangeChecker.java create mode 100644 api/src/test/java/org/cardanofoundation/rosetta/api/network/service/SlotRangeCheckerTest.java diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/block/model/domain/NetworkStatus.java b/api/src/main/java/org/cardanofoundation/rosetta/api/block/model/domain/NetworkStatus.java index 4e3b6aa8f..90d3fec9e 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/block/model/domain/NetworkStatus.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/block/model/domain/NetworkStatus.java @@ -8,6 +8,7 @@ import lombok.NoArgsConstructor; import org.openapitools.client.model.Peer; +import org.openapitools.client.model.SyncStatus; @Data @Builder @@ -17,5 +18,7 @@ public class NetworkStatus { private BlockIdentifierExtended latestBlock; private BlockIdentifierExtended genesisBlock; + private SyncStatus syncStatus; private List peers; + } diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/construction/service/CardanoConstructionServiceImpl.java b/api/src/main/java/org/cardanofoundation/rosetta/api/construction/service/CardanoConstructionServiceImpl.java index 14d21decb..b0c289e15 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/construction/service/CardanoConstructionServiceImpl.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/construction/service/CardanoConstructionServiceImpl.java @@ -126,7 +126,7 @@ public Array decodeTransaction(String encoded) { @Override public Long calculateTtl(Long ttlOffset) { - long absoluteSlot = offlineMode ? offlineSlotService.getCurrentSlotBasedOnTime() + long absoluteSlot = offlineMode ? offlineSlotService.getCurrentSlotBasedOnTimeWithFallback() : ledgerBlockService.findLatestBlockIdentifier().getSlot(); return absoluteSlot + ttlOffset; diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/construction/service/ConstructionApiServiceImpl.java b/api/src/main/java/org/cardanofoundation/rosetta/api/construction/service/ConstructionApiServiceImpl.java index 10b4b10af..121ffbe3a 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/construction/service/ConstructionApiServiceImpl.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/construction/service/ConstructionApiServiceImpl.java @@ -91,7 +91,7 @@ public ConstructionPreprocessResponse constructionPreprocessService( int relativeTtl = calculateRelativeTtl(metadata); - long currentSlotBasedOnTime = offlineSlotService.getCurrentSlotBasedOnTime() + relativeTtl; + long currentSlotBasedOnTime = offlineSlotService.getCurrentSlotBasedOnTimeWithFallback() + relativeTtl; NetworkEnum networkEnum = NetworkEnum.findByName( networkIdentifier.getNetwork()) @@ -216,7 +216,7 @@ public ConstructionPayloadsResponse constructionPayloadsService( private long calculateTtl(ConstructionPayloadsRequestMetadata metadata) { return metadata != null ? cardanoConstructionService.checkOrReturnDefaultTtl(metadata.getTtl()) : - offlineSlotService.getCurrentSlotBasedOnTime() + Constants.DEFAULT_RELATIVE_TTL; + offlineSlotService.getCurrentSlotBasedOnTimeWithFallback() + Constants.DEFAULT_RELATIVE_TTL; } private ProtocolParams convertProtocolParams(@Nullable ConstructionPayloadsRequestMetadata metadata) { diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/network/controller/NetworkApiImpl.java b/api/src/main/java/org/cardanofoundation/rosetta/api/network/controller/NetworkApiImpl.java index b11e7f976..5f4d27908 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/network/controller/NetworkApiImpl.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/network/controller/NetworkApiImpl.java @@ -23,31 +23,32 @@ public class NetworkApiImpl implements NetworkApi { @Override public ResponseEntity networkList( - @RequestBody MetadataRequest metadataRequest) { + @RequestBody MetadataRequest metadataRequest) { final NetworkListResponse networkListResponse = networkService.getNetworkList(metadataRequest); return ResponseEntity.ok(networkListResponse); } @Override public ResponseEntity networkOptions( - @RequestBody NetworkRequest networkRequest) { + @RequestBody NetworkRequest networkRequest) { networkService.verifyNetworkRequest(networkRequest.getNetworkIdentifier()); final NetworkOptionsResponse networkOptionsResponse = networkService.getNetworkOptions( - networkRequest); + networkRequest); return ResponseEntity.ok(networkOptionsResponse); } @Override public ResponseEntity networkStatus( - @RequestBody NetworkRequest networkRequest) { + @RequestBody NetworkRequest networkRequest) { if (offlineMode) { throw ExceptionFactory.notSupportedInOfflineMode(); } networkService.verifyNetworkRequest(networkRequest.getNetworkIdentifier()); + final NetworkStatusResponse networkStatusResponse = networkService.getNetworkStatus( - networkRequest); + networkRequest); return ResponseEntity.ok(networkStatusResponse); } diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/network/mapper/NetworkMapper.java b/api/src/main/java/org/cardanofoundation/rosetta/api/network/mapper/NetworkMapper.java index 7c9e808b0..3b650f64e 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/network/mapper/NetworkMapper.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/network/mapper/NetworkMapper.java @@ -17,6 +17,7 @@ public interface NetworkMapper { @Mapping(target = "currentBlockIdentifier.index", source = "latestBlock.number") @Mapping(target = "currentBlockIdentifier.hash", source = "latestBlock.hash") + @Mapping(target = "syncStatus", source = "syncStatus") @Mapping(target = "currentBlockTimestamp", expression = "java(java.util.concurrent.TimeUnit.SECONDS.toMillis(networkStatus.getLatestBlock().getBlockTimeInSeconds()))") @Mapping(target = "genesisBlockIdentifier.index", source = "genesisBlock.number", defaultValue = "0L") diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/GenesisDataProvider.java b/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/GenesisDataProvider.java new file mode 100644 index 000000000..a19bc77e8 --- /dev/null +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/GenesisDataProvider.java @@ -0,0 +1,7 @@ +package org.cardanofoundation.rosetta.api.network.service; + +public interface GenesisDataProvider { + + int getProtocolMagic(); + +} diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/GenesisDataProviderImpl.java b/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/GenesisDataProviderImpl.java new file mode 100644 index 000000000..a1628ef46 --- /dev/null +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/GenesisDataProviderImpl.java @@ -0,0 +1,54 @@ +package org.cardanofoundation.rosetta.api.network.service; + +import java.io.IOException; +import java.util.Map; +import javax.annotation.PostConstruct; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.cardanofoundation.rosetta.common.exception.ExceptionFactory; +import org.cardanofoundation.rosetta.common.util.FileUtils; + +import static org.cardanofoundation.rosetta.common.util.Constants.NETWORK_MAGIC_NAME; + +@Service +@Slf4j +@RequiredArgsConstructor +public class GenesisDataProviderImpl implements GenesisDataProvider { + + @Value("${cardano.rosetta.GENESIS_SHELLEY_PATH}") + private String genesisShelleyPath; + + private int protocolMagic; + + @PostConstruct + public void init() { + Map jsonMap = loadGenesisShelleyConfig(); + protocolMagic = (Integer) jsonMap.get(NETWORK_MAGIC_NAME); + + log.info("Protocol magic number: {} loaded from genesis config json", protocolMagic); + } + + @Override + public int getProtocolMagic() { + return protocolMagic; + } + + private Map loadGenesisShelleyConfig() { + try { + String content = FileUtils.fileReader(genesisShelleyPath); + + return new ObjectMapper().readValue(content, new TypeReference<>() { + }); + } catch (IOException e) { + throw ExceptionFactory.configNotFoundException(genesisShelleyPath); + } + } + +} diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/NetworkService.java b/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/NetworkService.java index 5a986a0ad..b0a91dc9d 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/NetworkService.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/NetworkService.java @@ -1,6 +1,5 @@ package org.cardanofoundation.rosetta.api.network.service; - import com.bloxbean.cardano.client.common.model.Network; import org.openapitools.client.model.MetadataRequest; import org.openapitools.client.model.NetworkIdentifier; @@ -10,6 +9,7 @@ import org.openapitools.client.model.NetworkStatusResponse; public interface NetworkService { + NetworkListResponse getNetworkList(final MetadataRequest metadataRequest); NetworkOptionsResponse getNetworkOptions(final NetworkRequest networkRequest); diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/NetworkServiceImpl.java b/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/NetworkServiceImpl.java index e24bbfd99..3cb726f8c 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/NetworkServiceImpl.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/NetworkServiceImpl.java @@ -2,37 +2,21 @@ import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import javax.annotation.PostConstruct; +import java.util.*; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import lombok.val; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Service; import com.bloxbean.cardano.client.common.model.Network; import com.bloxbean.cardano.client.common.model.Networks; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.parser.OpenAPIV3Parser; -import org.openapitools.client.model.Allow; +import org.openapitools.client.model.*; import org.openapitools.client.model.Error; -import org.openapitools.client.model.MetadataRequest; -import org.openapitools.client.model.NetworkIdentifier; -import org.openapitools.client.model.NetworkListResponse; -import org.openapitools.client.model.NetworkOptionsResponse; -import org.openapitools.client.model.NetworkRequest; -import org.openapitools.client.model.NetworkStatusResponse; -import org.openapitools.client.model.OperationStatus; -import org.openapitools.client.model.Peer; -import org.openapitools.client.model.Version; import org.cardanofoundation.rosetta.api.block.model.domain.BlockIdentifierExtended; import org.cardanofoundation.rosetta.api.block.model.domain.NetworkStatus; @@ -41,42 +25,40 @@ import org.cardanofoundation.rosetta.common.enumeration.OperationType; import org.cardanofoundation.rosetta.common.enumeration.OperationTypeStatus; import org.cardanofoundation.rosetta.common.exception.ExceptionFactory; +import org.cardanofoundation.rosetta.common.time.OfflineSlotService; import org.cardanofoundation.rosetta.common.util.Constants; -import org.cardanofoundation.rosetta.common.util.FileUtils; import org.cardanofoundation.rosetta.common.util.RosettaConstants; -import org.cardanofoundation.rosetta.config.RosettaConfig; @Service @Slf4j @RequiredArgsConstructor public class NetworkServiceImpl implements NetworkService { - private final RosettaConfig rosettaConfig; private final LedgerBlockService ledgerBlockService; + private final OfflineSlotService offlineSlotService; private final NetworkMapper networkMapper; private final TopologyConfigService topologyConfigService; private final ResourceLoader resourceLoader; - - private Integer cachedMagicNumber; + private final GenesisDataProvider genesisDataProvider; + private final SlotRangeChecker slotRangeChecker; @Value("${cardano.rosetta.GENESIS_SHELLEY_PATH}") private String genesisShelleyPath; + @Value("${cardano.rosetta.CARDANO_NODE_VERSION}") private String cardanoNodeVersion; + @Value("${cardano.rosetta.middleware-version}") private String revision; - @PostConstruct - public void init() { - Map jsonMap = loadGenesisShelleyConfig(); - cachedMagicNumber = (Integer) jsonMap.get(Constants.NETWORK_MAGIC_NAME); - log.info("Magic number {} loaded from genesis config json", cachedMagicNumber); - } + @Value("${cardano.rosetta.ALLOWED_SLOTS_DELTA:100}") + private int allowedSlotsDelta; @Override public NetworkListResponse getNetworkList(MetadataRequest metadataRequest) { log.info("[networkList] Looking for all supported networks"); Network supportedNetwork = getSupportedNetwork(); + return networkMapper.toNetworkListResponse(supportedNetwork); } @@ -86,42 +68,42 @@ public NetworkOptionsResponse getNetworkOptions(NetworkRequest networkRequest) { String rosettaVersion = getRosettaVersion(); OperationStatus success = new OperationStatus().successful(true) - .status(OperationTypeStatus.SUCCESS.getValue()); + .status(OperationTypeStatus.SUCCESS.getValue()); OperationStatus invalid = new OperationStatus().successful(false) - .status(OperationTypeStatus.INVALID.getValue()); + .status(OperationTypeStatus.INVALID.getValue()); List operationStatuses = List.of(success, invalid); return NetworkOptionsResponse.builder() - .version(new Version().nodeVersion(cardanoNodeVersion) - .rosettaVersion(rosettaVersion) - .middlewareVersion(revision) - .metadata(new LinkedHashMap<>())) - .allow(new Allow().operationStatuses(operationStatuses) - .operationTypes( - Arrays.stream(OperationType.values()).map(OperationType::getValue).toList()) - .errors(RosettaConstants.ROSETTA_ERRORS.stream() - .map(error -> - new Error().code(error.getCode()) - .message(error.getMessage()) - .retriable(error.isRetriable()) - .description(error.getDescription()) - .code(error.getCode()) - ) - .sorted(Comparator.comparingInt(Error::getCode)) - .toList()) - .historicalBalanceLookup(true) - .callMethods(new ArrayList<>()) - .mempoolCoins(false)) - .build(); + .version(new Version().nodeVersion(cardanoNodeVersion) + .rosettaVersion(rosettaVersion) + .middlewareVersion(revision) + .metadata(new LinkedHashMap<>())) + .allow(new Allow().operationStatuses(operationStatuses) + .operationTypes( + Arrays.stream(OperationType.values()).map(OperationType::getValue).toList()) + .errors(RosettaConstants.ROSETTA_ERRORS.stream() + .map(error -> + new Error().code(error.getCode()) + .message(error.getMessage()) + .retriable(error.isRetriable()) + .description(error.getDescription()) + .code(error.getCode()) + ) + .sorted(Comparator.comparingInt(Error::getCode)) + .toList()) + .historicalBalanceLookup(true) + .callMethods(new ArrayList<>()) + .mempoolCoins(false)) + .build(); } private String getRosettaVersion() { try { InputStream openAPIStream = resourceLoader.getResource( - Constants.ROSETTA_API_PATH).getInputStream(); + Constants.ROSETTA_API_PATH).getInputStream(); OpenAPI openAPI = new OpenAPIV3Parser().readContents(new String(openAPIStream.readAllBytes()), - null, null) - .getOpenAPI(); + null, null) + .getOpenAPI(); return openAPI.getInfo().getVersion(); } catch (IOException e) { throw ExceptionFactory.configNotFoundException(Constants.ROSETTA_API_PATH); @@ -139,13 +121,15 @@ public NetworkStatusResponse getNetworkStatus(NetworkRequest networkRequest) { @Override public Network getSupportedNetwork() { - Integer networkMagic = getNetworkMagic(); + int networkMagic = genesisDataProvider.getProtocolMagic(); + return switch (networkMagic) { case Constants.MAINNET_NETWORK_MAGIC -> Networks.mainnet(); case Constants.PREPROD_NETWORK_MAGIC -> Networks.preprod(); case Constants.PREVIEW_NETWORK_MAGIC -> Networks.preview(); case Constants.SANCHONET_NETWORK_MAGIC -> new Network(0b0000, Constants.SANCHONET_NETWORK_MAGIC); case Constants.DEVKIT_NETWORK_MAGIC -> new Network(0b0000, Constants.DEVKIT_NETWORK_MAGIC); + default -> throw ExceptionFactory.invalidNetworkError(); }; } @@ -162,11 +146,28 @@ private NetworkStatus networkStatus() { List peers = topologyConfigService.getPeers(); - return NetworkStatus.builder() - .latestBlock(latestBlock) - .genesisBlock(genesisBlock) - .peers(peers) - .build(); + val networkStatusBuilder = NetworkStatus.builder() + .latestBlock(latestBlock) + .genesisBlock(genesisBlock) + .peers(peers); + + calculateSyncStatus(latestBlock).ifPresent(networkStatusBuilder::syncStatus); + + return networkStatusBuilder.build(); + } + + private Optional calculateSyncStatus(BlockIdentifierExtended latestBlock) { + return offlineSlotService.getCurrentSlotBasedOnTime().map(slotBasedOnTime -> { + long slotBasedOnLatestBlock = latestBlock.getSlot(); + + boolean isSynced = slotRangeChecker.isSlotWithinEpsilon(slotBasedOnTime, slotBasedOnLatestBlock, allowedSlotsDelta); + + return SyncStatus.builder() + .targetIndex(slotBasedOnTime) + .currentIndex(slotBasedOnLatestBlock) + .synced(isSynced) + .build(); + }); } @Override @@ -210,16 +211,5 @@ private boolean verifyNetwork(String network) { } } - public Integer getNetworkMagic() { - return cachedMagicNumber; - } - private Map loadGenesisShelleyConfig() { - try { - String content = FileUtils.fileReader(genesisShelleyPath); - return new ObjectMapper().readValue(content, new TypeReference>() {}); - } catch (IOException e) { - throw ExceptionFactory.configNotFoundException(genesisShelleyPath); - } - } } diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/SlotRangeChecker.java b/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/SlotRangeChecker.java new file mode 100644 index 000000000..87ad4d78d --- /dev/null +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/SlotRangeChecker.java @@ -0,0 +1,21 @@ +package org.cardanofoundation.rosetta.api.network.service; + +import org.springframework.stereotype.Service; + +@Service +public class SlotRangeChecker { + + public boolean isSlotWithinEpsilon(long slotBasedOnTime, + long slotBasedOnLatestBlock, + long epsilon) { + assert slotBasedOnTime >= 0; + assert slotBasedOnLatestBlock >= 0; + + if (epsilon < 0) { + throw new IllegalArgumentException("Epsilon must be non-negative"); + } + + return Math.abs(slotBasedOnTime - slotBasedOnLatestBlock) <= epsilon; + } + +} diff --git a/api/src/main/java/org/cardanofoundation/rosetta/common/time/OfflineSlotService.java b/api/src/main/java/org/cardanofoundation/rosetta/common/time/OfflineSlotService.java index b97d554ec..23c4884eb 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/common/time/OfflineSlotService.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/common/time/OfflineSlotService.java @@ -1,7 +1,11 @@ package org.cardanofoundation.rosetta.common.time; +import java.util.Optional; + public interface OfflineSlotService { - long getCurrentSlotBasedOnTime(); + long getCurrentSlotBasedOnTimeWithFallback(); + + Optional getCurrentSlotBasedOnTime(); } diff --git a/api/src/main/java/org/cardanofoundation/rosetta/common/time/OfflineSlotServiceImpl.java b/api/src/main/java/org/cardanofoundation/rosetta/common/time/OfflineSlotServiceImpl.java index da59ee305..77e11881c 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/common/time/OfflineSlotServiceImpl.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/common/time/OfflineSlotServiceImpl.java @@ -1,6 +1,7 @@ package org.cardanofoundation.rosetta.common.time; import java.time.*; +import java.util.Optional; import javax.annotation.Nullable; import lombok.RequiredArgsConstructor; @@ -39,19 +40,33 @@ public class OfflineSlotServiceImpl implements OfflineSlotService { protected CardanoConverters cardanoConverters; @Override - public long getCurrentSlotBasedOnTime() { + public long getCurrentSlotBasedOnTimeWithFallback() { if (cardanoConverters != null) { - LocalDateTime nowDateTime = LocalDateTime.now(clock); - ZoneOffset zoneOffset = ZonedDateTime.now(zoneId).getOffset(); + return timeToAbsoluteSlotNo(); + } - if (nowDateTime.toInstant(zoneOffset).isBefore(shellyStartTime)) { - throw new ApiException(ExceptionFactory.misconfiguredTime(nowDateTime).getError()); - } + return shelleyStartSlot; + } - return cardanoConverters.time().toSlot(nowDateTime); + @Override + public Optional getCurrentSlotBasedOnTime() { + if (cardanoConverters != null) { + return Optional.of(timeToAbsoluteSlotNo()); } - return shelleyStartSlot; + return Optional.empty(); + } + + private Long timeToAbsoluteSlotNo() { + LocalDateTime nowDateTime = LocalDateTime.now(clock); + ZoneOffset zoneOffset = ZonedDateTime.now(zoneId).getOffset(); + + if (nowDateTime.toInstant(zoneOffset).isBefore(shellyStartTime)) { + throw new ApiException(ExceptionFactory.misconfiguredTime(nowDateTime).getError()); + + } + + return cardanoConverters.time().toSlot(nowDateTime); } } diff --git a/api/src/main/java/org/cardanofoundation/rosetta/config/CardanoConvertersConfig.java b/api/src/main/java/org/cardanofoundation/rosetta/config/CardanoConvertersConfig.java index 1a466236e..a30401979 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/config/CardanoConvertersConfig.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/config/CardanoConvertersConfig.java @@ -6,6 +6,7 @@ import java.time.ZonedDateTime; import jakarta.annotation.Nullable; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Qualifier; @@ -14,49 +15,53 @@ import org.cardanofoundation.conversions.CardanoConverters; import org.cardanofoundation.conversions.ClasspathConversionsFactory; -import org.cardanofoundation.conversions.domain.NetworkType; -import org.cardanofoundation.rosetta.api.network.service.NetworkService; +import org.cardanofoundation.rosetta.api.network.service.GenesisDataProvider; import org.cardanofoundation.rosetta.common.util.Constants; +import static org.cardanofoundation.conversions.domain.NetworkType.*; import static org.cardanofoundation.rosetta.common.util.Constants.MAINNET_NETWORK_MAGIC; @Configuration @Slf4j +@RequiredArgsConstructor public class CardanoConvertersConfig { + private final GenesisDataProvider genesisDataProvider; + @Bean @Nullable - public CardanoConverters cardanoConverters(NetworkService networkService) { - if (networkService.getSupportedNetwork() == null) { // mostly helper for unit tests and integration tests - return null; - } - - long protocolMagic = networkService.getSupportedNetwork().getProtocolMagic(); + public CardanoConverters cardanoConverters() { + int protocolMagic = genesisDataProvider.getProtocolMagic(); log.info("Creating CardanoConverters for network magic: {}", protocolMagic); if (protocolMagic == MAINNET_NETWORK_MAGIC) { - return ClasspathConversionsFactory.createConverters(NetworkType.MAINNET); + log.info("Creating CardanoConverters for mainnet"); + return ClasspathConversionsFactory.createConverters(MAINNET); } if (protocolMagic == Constants.PREPROD_NETWORK_MAGIC) { - return ClasspathConversionsFactory.createConverters(NetworkType.PREPROD); + log.info("Creating CardanoConverters for preprod"); + return ClasspathConversionsFactory.createConverters(PREPROD); } if (protocolMagic == Constants.PREVIEW_NETWORK_MAGIC) { - return ClasspathConversionsFactory.createConverters(NetworkType.PREVIEW); + log.info("Creating CardanoConverters for preview"); + return ClasspathConversionsFactory.createConverters(PREVIEW); } if (protocolMagic == Constants.SANCHONET_NETWORK_MAGIC) { - return ClasspathConversionsFactory.createConverters(NetworkType.SANCHONET); + log.info("Creating CardanoConverters for sanchonet"); + return ClasspathConversionsFactory.createConverters(SANCHONET); } if (protocolMagic == Constants.DEVKIT_NETWORK_MAGIC) { + log.info("Creating CardanoConverters for devkit, no converters available"); // Cardano Converters for DevKit is not supported but we still need to return something sensible return null; } - throw new IllegalArgumentException("Unsupported network magic: " + protocolMagic); + throw new IllegalArgumentException("Unsupported network magic: %d".formatted(protocolMagic)); } @Bean diff --git a/api/src/test/java/org/cardanofoundation/rosetta/api/network/service/NetworkServiceImplTest.java b/api/src/test/java/org/cardanofoundation/rosetta/api/network/service/NetworkServiceImplTest.java index 54b4f6889..6fff8827d 100644 --- a/api/src/test/java/org/cardanofoundation/rosetta/api/network/service/NetworkServiceImplTest.java +++ b/api/src/test/java/org/cardanofoundation/rosetta/api/network/service/NetworkServiceImplTest.java @@ -116,4 +116,6 @@ private NetworkIdentifier createNetworkIdentifier(String blockchain, String netw .network(network) .build(); } + + } diff --git a/api/src/test/java/org/cardanofoundation/rosetta/api/network/service/SlotRangeCheckerTest.java b/api/src/test/java/org/cardanofoundation/rosetta/api/network/service/SlotRangeCheckerTest.java new file mode 100644 index 000000000..88b40df38 --- /dev/null +++ b/api/src/test/java/org/cardanofoundation/rosetta/api/network/service/SlotRangeCheckerTest.java @@ -0,0 +1,35 @@ +package org.cardanofoundation.rosetta.api.network.service; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class SlotRangeCheckerTest { + + @Test + void testIsSlotWithinEpsilonWhenWithinRange() { + SlotRangeChecker slotRangeChecker = new SlotRangeChecker(); + assertTrue(slotRangeChecker.isSlotWithinEpsilon(100, 105, 10)); + } + + @Test + void testIsSlotWithinEpsilonWhenOutOfRange() { + SlotRangeChecker slotRangeChecker = new SlotRangeChecker(); + assertFalse(slotRangeChecker.isSlotWithinEpsilon(100, 120, 10)); + } + + @Test + void testIsSlotWithinEpsilonWhenAtBoundary() { + SlotRangeChecker slotRangeChecker = new SlotRangeChecker(); + assertTrue(slotRangeChecker.isSlotWithinEpsilon(100, 110, 10)); + } + + @Test + void testIsSlotWithinEpsilonThrowsExceptionWhenEpsilonNegative() { + SlotRangeChecker slotRangeChecker = new SlotRangeChecker(); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, + () -> slotRangeChecker.isSlotWithinEpsilon(100, 105, -1)); + assertEquals("Epsilon must be non-negative", exception.getMessage()); + } + +} diff --git a/api/src/test/java/org/cardanofoundation/rosetta/common/time/OfflineSlotServiceImplTest.java b/api/src/test/java/org/cardanofoundation/rosetta/common/time/OfflineSlotServiceImplTest.java index ba5db3b85..9b500dc83 100644 --- a/api/src/test/java/org/cardanofoundation/rosetta/common/time/OfflineSlotServiceImplTest.java +++ b/api/src/test/java/org/cardanofoundation/rosetta/common/time/OfflineSlotServiceImplTest.java @@ -4,6 +4,7 @@ import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; +import java.util.Optional; import org.mockito.Mock; import org.mockito.Spy; @@ -35,15 +36,20 @@ class OfflineSlotServiceImplTest { private final Instant shellyStartTime = Instant.parse("2020-07-29T21:44:51Z"); private final long shelleyStartSlot = 1000L; // Example slot value - private OfflineSlotServiceImpl offlineSlotService; + private OfflineSlotServiceImpl offlineSlotServiceWithConverters; + private OfflineSlotServiceImpl offlineSlotServiceWithoutConverters; @BeforeEach @SuppressWarnings("java:S5786") public void setup() { - this.offlineSlotService = new OfflineSlotServiceImpl(clock, zoneOffset); - this.offlineSlotService.cardanoConverters = cardanoConverters; - this.offlineSlotService.shelleyStartSlot = shelleyStartSlot; - this.offlineSlotService.shellyStartTime = shellyStartTime; + this.offlineSlotServiceWithConverters = new OfflineSlotServiceImpl(clock, zoneOffset); + this.offlineSlotServiceWithConverters.cardanoConverters = cardanoConverters; + this.offlineSlotServiceWithConverters.shelleyStartSlot = shelleyStartSlot; + this.offlineSlotServiceWithConverters.shellyStartTime = shellyStartTime; + + this.offlineSlotServiceWithoutConverters = new OfflineSlotServiceImpl(clock, zoneOffset); + this.offlineSlotServiceWithoutConverters.shelleyStartSlot = shelleyStartSlot; + this.offlineSlotServiceWithoutConverters.shellyStartTime = shellyStartTime; } @Test @@ -54,7 +60,7 @@ void shouldReturnSlotBasedOnCurrentTime_WhenCardanoConvertersAvailable() { when(clock.getZone()).thenReturn(zoneOffset); // When - long slot = offlineSlotService.getCurrentSlotBasedOnTime(); + long slot = offlineSlotServiceWithConverters.getCurrentSlotBasedOnTimeWithFallback(); // Then assertThat(slot).isEqualTo(105366319L); @@ -68,7 +74,7 @@ void shouldThrowException_WhenTimeIsBeforeShellyStartTime() { when(clock.getZone()).thenReturn(zoneOffset); // When / Then - assertThatThrownBy(() -> offlineSlotService.getCurrentSlotBasedOnTime()) + assertThatThrownBy(() -> offlineSlotServiceWithConverters.getCurrentSlotBasedOnTimeWithFallback()) .isInstanceOf(ApiException.class); } @@ -80,11 +86,37 @@ void shouldVerifyCardanoConvertersSlotMethodIsCalled() { when(clock.getZone()).thenReturn(zoneOffset); // When - long slot = offlineSlotService.getCurrentSlotBasedOnTime(); + long slot = offlineSlotServiceWithConverters.getCurrentSlotBasedOnTimeWithFallback(); // Then assertThat(slot).isEqualTo(105366319L); verify(cardanoConverters, atLeastOnce()).time(); } + @Test + void shouldVerifyCardanoConvertersSlotMethodIsCalledWithoutFallback() { + // Given + LocalDateTime now = LocalDateTime.of(2023, 10, 10, 10, 10, 10); + when(clock.instant()).thenReturn(now.toInstant(zoneOffset)); + when(clock.getZone()).thenReturn(zoneOffset); + + // When + Optional slotM = offlineSlotServiceWithConverters.getCurrentSlotBasedOnTime(); + + // Then + assertThat(slotM).isPresent(); + assertThat(slotM.orElseThrow()).isEqualTo(105366319L); + verify(cardanoConverters, atLeastOnce()).time(); + } + + @Test + public void cardanoConvertersNotAvailableNoCurrentSlot() { + assertThat(offlineSlotServiceWithoutConverters.getCurrentSlotBasedOnTime()).isNotPresent(); + } + + @Test + public void cardanoConvertersNotAvailableCurrentSlotFallback() { + assertThat(offlineSlotServiceWithoutConverters.getCurrentSlotBasedOnTimeWithFallback()).isEqualTo(shelleyStartSlot); + } + } diff --git a/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/service/AccountServiceImpl.java b/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/service/AccountServiceImpl.java index 86b5771ef..01ce953ae 100644 --- a/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/service/AccountServiceImpl.java +++ b/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/service/AccountServiceImpl.java @@ -1,22 +1,24 @@ package org.cardanofoundation.rosetta.yaciindexer.service; +import java.math.BigInteger; +import java.time.Duration; +import java.util.Optional; +import java.util.Set; +import jakarta.annotation.Nullable; + +import lombok.extern.slf4j.Slf4j; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.stereotype.Service; import com.bloxbean.cardano.client.address.Address; import com.bloxbean.cardano.yaci.core.protocol.localstate.api.Era; import com.bloxbean.cardano.yaci.core.protocol.localstate.queries.DelegationsAndRewardAccountsQuery; import com.bloxbean.cardano.yaci.core.protocol.localstate.queries.DelegationsAndRewardAccountsResult; import com.bloxbean.cardano.yaci.helper.LocalClientProvider; import com.bloxbean.cardano.yaci.store.core.service.local.LocalClientProviderManager; -import jakarta.annotation.Nullable; -import lombok.extern.slf4j.Slf4j; -import org.cardanofoundation.rosetta.yaciindexer.domain.model.StakeAccountRewardInfo; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; -import org.springframework.stereotype.Service; import reactor.core.publisher.Mono; -import java.math.BigInteger; -import java.time.Duration; -import java.util.Optional; -import java.util.Set; +import org.cardanofoundation.rosetta.yaciindexer.domain.model.StakeAccountRewardInfo; @Service @Slf4j diff --git a/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/service/TransactionScriptSizeCalculatorImpl.java b/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/service/TransactionScriptSizeCalculatorImpl.java index 6829c1573..ad8934e67 100644 --- a/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/service/TransactionScriptSizeCalculatorImpl.java +++ b/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/service/TransactionScriptSizeCalculatorImpl.java @@ -1,5 +1,10 @@ package org.cardanofoundation.rosetta.yaciindexer.service; +import java.util.List; + +import lombok.extern.slf4j.Slf4j; + +import org.springframework.stereotype.Service; import co.nstant.in.cbor.model.Array; import co.nstant.in.cbor.model.ByteString; import co.nstant.in.cbor.model.Map; @@ -10,11 +15,8 @@ import com.bloxbean.cardano.yaci.core.model.PlutusScript; import com.bloxbean.cardano.yaci.helper.model.Transaction; import com.fasterxml.jackson.core.JsonProcessingException; -import lombok.extern.slf4j.Slf4j; -import org.cardanofoundation.rosetta.yaciindexer.domain.model.TransactionBuildingConstants; -import org.springframework.stereotype.Service; -import java.util.List; +import org.cardanofoundation.rosetta.yaciindexer.domain.model.TransactionBuildingConstants; import static com.bloxbean.cardano.client.util.HexUtil.decodeHexString; import static org.cardanofoundation.rosetta.yaciindexer.domain.model.TransactionBuildingConstants.*; diff --git a/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/service/TransactionSizeCalculatorImpl.java b/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/service/TransactionSizeCalculatorImpl.java index 7cc7d0578..ed20bf15e 100644 --- a/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/service/TransactionSizeCalculatorImpl.java +++ b/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/service/TransactionSizeCalculatorImpl.java @@ -1,9 +1,10 @@ package org.cardanofoundation.rosetta.yaciindexer.service; -import co.nstant.in.cbor.model.Map; -import com.bloxbean.cardano.yaci.core.util.CborSerializationUtil; import lombok.extern.slf4j.Slf4j; + import org.springframework.stereotype.Service; +import co.nstant.in.cbor.model.Map; +import com.bloxbean.cardano.yaci.core.util.CborSerializationUtil; @Service @Slf4j diff --git a/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/stores/txsize/CustomTransactionSizeStore.java b/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/stores/txsize/CustomTransactionSizeStore.java index 176a24c52..b0cbcf668 100644 --- a/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/stores/txsize/CustomTransactionSizeStore.java +++ b/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/stores/txsize/CustomTransactionSizeStore.java @@ -1,5 +1,14 @@ package org.cardanofoundation.rosetta.yaciindexer.stores.txsize; +import java.util.List; +import java.util.Optional; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import co.nstant.in.cbor.model.Array; import co.nstant.in.cbor.model.DataItem; import co.nstant.in.cbor.model.Map; @@ -8,19 +17,12 @@ import com.bloxbean.cardano.yaci.core.util.CborSerializationUtil; import com.bloxbean.cardano.yaci.helper.model.Transaction; import com.bloxbean.cardano.yaci.store.events.TransactionEvent; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; + import org.cardanofoundation.rosetta.yaciindexer.domain.model.TransactionBuildingConstants; import org.cardanofoundation.rosetta.yaciindexer.service.TransactionScriptSizeCalculator; import org.cardanofoundation.rosetta.yaciindexer.service.TransactionSizeCalculator; import org.cardanofoundation.rosetta.yaciindexer.stores.txsize.model.TransactionSizeEntity; import org.cardanofoundation.rosetta.yaciindexer.stores.txsize.model.TransactionSizeRepository; -import org.springframework.context.event.EventListener; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Optional; import static co.nstant.in.cbor.model.SimpleValue.TRUE; import static org.cardanofoundation.rosetta.yaciindexer.domain.model.TransactionBuildingConstants.*; diff --git a/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/stores/txsize/model/TransactionSizeEntity.java b/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/stores/txsize/model/TransactionSizeEntity.java index 0b1c2f25c..7000f36be 100644 --- a/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/stores/txsize/model/TransactionSizeEntity.java +++ b/yaci-indexer/src/main/java/org/cardanofoundation/rosetta/yaciindexer/stores/txsize/model/TransactionSizeEntity.java @@ -4,6 +4,7 @@ import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; + import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; diff --git a/yaci-indexer/src/test/java/org/cardanofoundation/rosetta/yaciindexer/stores/txsize/CustomTransactionSizeStoreTest.java b/yaci-indexer/src/test/java/org/cardanofoundation/rosetta/yaciindexer/stores/txsize/CustomTransactionSizeStoreTest.java index 0267c7e16..d80f0e632 100644 --- a/yaci-indexer/src/test/java/org/cardanofoundation/rosetta/yaciindexer/stores/txsize/CustomTransactionSizeStoreTest.java +++ b/yaci-indexer/src/test/java/org/cardanofoundation/rosetta/yaciindexer/stores/txsize/CustomTransactionSizeStoreTest.java @@ -1,20 +1,22 @@ package org.cardanofoundation.rosetta.yaciindexer.stores.txsize; +import java.util.List; + import com.bloxbean.cardano.yaci.store.events.TransactionEvent; import org.assertj.core.api.Assertions; +import org.mockito.*; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + import org.cardanofoundation.rosetta.yaciindexer.TestDataGenerator; import org.cardanofoundation.rosetta.yaciindexer.service.TransactionScriptSizeCalculator; import org.cardanofoundation.rosetta.yaciindexer.service.TransactionScriptSizeCalculatorImpl; import org.cardanofoundation.rosetta.yaciindexer.service.TransactionSizeCalculatorImpl; import org.cardanofoundation.rosetta.yaciindexer.stores.txsize.model.TransactionSizeEntity; import org.cardanofoundation.rosetta.yaciindexer.stores.txsize.model.TransactionSizeRepository; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.*; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.util.List; @ExtendWith(MockitoExtension.class) class CustomTransactionSizeStoreTest { From 5a98d203ce095593387cc91322f7dca61482ebdc Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 30 Apr 2025 16:00:08 +0200 Subject: [PATCH 5/6] chore: 1.2.8 version updated. --- README.md | 4 ++-- pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8b920bdfc..a545036e7 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ For every Release we provide pre-built docker images stored in the DockerHub Rep To start it use the following command: ```bash - docker run --name rosetta -v {CUSTOM_MOUNT_PATH}:/node --env-file ./docker/.env.dockerfile --env-file ./docker/.env.docker-profile-mid-level -p 8082:8082 --shm-size=4g -d cardanofoundation/cardano-rosetta-java:1.2.7 + docker run --name rosetta -v {CUSTOM_MOUNT_PATH}:/node --env-file ./docker/.env.dockerfile --env-file ./docker/.env.docker-profile-mid-level -p 8082:8082 --shm-size=4g -d cardanofoundation/cardano-rosetta-java:1.2.8 ``` Changes to the configuration can be made by adjusting the `docker/.env.dockerfile` file. For more information on the environment variables, please refer to the [documentation](https://cardano-foundation.github.io/cardano-rosetta-java/docs/install-and-deploy/env-vars). @@ -108,7 +108,7 @@ Changes to the configuration can be made by adjusting the `docker/.env.dockerfil If you want to use the `cardano-submit-api` you can additionally expose port `8090`. It can then be used to submit raw cbor transaction (API documentation here: [Link](https://input-output-hk.github.io/cardano-rest/submit-api/)) ```bash - docker run --name rosetta -v {CUSTOM_MOUNT_PATH}:/node --env-file ./docker/.env.dockerfile --env-file ./docker/.env.docker-profile-mid-level -p 8090:8090 -p 8082:8082 --shm-size=4g -d cardanofoundation/cardano-rosetta-java:1.2.7 + docker run --name rosetta -v {CUSTOM_MOUNT_PATH}:/node --env-file ./docker/.env.dockerfile --env-file ./docker/.env.docker-profile-mid-level -p 8090:8090 -p 8082:8082 --shm-size=4g -d cardanofoundation/cardano-rosetta-java:1.2.8 ``` ### Docker compose diff --git a/pom.xml b/pom.xml index 5645ee421..7ebf8261b 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ - 1.2.7 + 1.2.8 21 UTF-8 3.4.3 From 6c98ee806e9a0fdd5e1d3f99025d96a146611433 Mon Sep 17 00:00:00 2001 From: Mateusz Czeladka Date: Wed, 30 Apr 2025 17:09:51 +0200 Subject: [PATCH 6/6] refactor: we do not need to be overly protective if we are re-indexing full db now, remove unnecessary complexity. --- .../V1.0_1100_0__rosetta_app_address_utxo.sql | 1 + .../V1.0_900_0__rosetta_app_addres_utxo.sql | 11 ----------- 2 files changed, 1 insertion(+), 11 deletions(-) create mode 100644 yaci-indexer/src/main/resources/db/store/postgresql/V1.0_1100_0__rosetta_app_address_utxo.sql delete mode 100644 yaci-indexer/src/main/resources/db/store/postgresql/V1.0_900_0__rosetta_app_addres_utxo.sql diff --git a/yaci-indexer/src/main/resources/db/store/postgresql/V1.0_1100_0__rosetta_app_address_utxo.sql b/yaci-indexer/src/main/resources/db/store/postgresql/V1.0_1100_0__rosetta_app_address_utxo.sql new file mode 100644 index 000000000..8ffd8c463 --- /dev/null +++ b/yaci-indexer/src/main/resources/db/store/postgresql/V1.0_1100_0__rosetta_app_address_utxo.sql @@ -0,0 +1 @@ +CREATE INDEX idx_address_utxo_tx_hash ON address_utxo USING btree (tx_hash); \ No newline at end of file diff --git a/yaci-indexer/src/main/resources/db/store/postgresql/V1.0_900_0__rosetta_app_addres_utxo.sql b/yaci-indexer/src/main/resources/db/store/postgresql/V1.0_900_0__rosetta_app_addres_utxo.sql deleted file mode 100644 index 05bfb309f..000000000 --- a/yaci-indexer/src/main/resources/db/store/postgresql/V1.0_900_0__rosetta_app_addres_utxo.sql +++ /dev/null @@ -1,11 +0,0 @@ -DO $$ -BEGIN - IF NOT EXISTS ( - SELECT 1 FROM pg_indexes - WHERE indexname = 'idx_address_utxo_tx_hash' - AND tablename = 'address_utxo' - AND schemaname = current_schema() - ) THEN - CREATE INDEX idx_address_utxo_tx_hash ON address_utxo USING btree (tx_hash); - END IF; -END $$; \ No newline at end of file