Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .github/workflows/verify-proto-go-generation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Verify Proto Go Generation

on:
pull_request:
paths:
- "inference-chain/**/*.proto"
- "inference-chain/**/*.pb.go"
- "inference-chain/**/*.pulsar.go"

jobs:
verify-proto-go-generation:
name: Verify `ignite generate proto-go`
runs-on: ubuntu-24.04
permissions:
contents: read
env:
IGNITE_VERSION: "28.10.0"
IGNITE_TARBALL: "ignite_28.10.0_linux_amd64.tar.gz"

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24.2"

- name: Install Ignite CLI
run: |
curl -fsSLo "/tmp/${IGNITE_TARBALL}" \
"https://github.com/ignite/cli/releases/download/v${IGNITE_VERSION}/${IGNITE_TARBALL}"
curl -fsSLo /tmp/ignite_checksums.txt \
"https://github.com/ignite/cli/releases/download/v${IGNITE_VERSION}/ignite_${IGNITE_VERSION}_checksums.txt"
grep " ${IGNITE_TARBALL}$" /tmp/ignite_checksums.txt | sed "s# ${IGNITE_TARBALL}\$# /tmp/${IGNITE_TARBALL}#" | sha256sum -c -
mkdir -p "$RUNNER_TEMP/bin"
tar -xzf "/tmp/${IGNITE_TARBALL}" -C "$RUNNER_TEMP/bin" ignite
chmod +x "$RUNNER_TEMP/bin/ignite"
echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH"
"$RUNNER_TEMP/bin/ignite" version

- name: Run proto-go generation
working-directory: ./inference-chain
env:
CI: "true"
DO_NOT_TRACK: "true"
IGNT_CONFIG_DIR: "${{ runner.temp }}/ignite-config"
run: |
mkdir -p "$IGNT_CONFIG_DIR"
ignite generate proto-go --yes

- name: Verify no generated changes
run: |
if [[ -n "$(git status --porcelain)" ]]; then
echo "Proto generation produced changes. Please run 'ignite generate proto-go' in inference-chain and commit the result."
echo
git status --short
echo
git diff --stat
exit 1
fi
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ run-parallel-tests/
inference-chain/proto/github.com/
inference-chain/proto/api/
inference-chain/proto/**/module/*.pb.go

# Generated JSONLs
mlnode/packages/benchmarks/data/inference_results/*
7 changes: 6 additions & 1 deletion decentralized-api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@ FROM golang:1.24.2-alpine3.20 AS builder
ARG BUILD_FLAGS
ARG GOOS
ARG GOARCH
ARG BLST_PORTABLE=0

ENV GOOS=${GOOS} \
GOARCH=${GOARCH} \
CGO_ENABLED=1 \
GO111MODULE=on \
GOCACHE=/root/.cache/go-build \
GOMODCACHE=/go/pkg/mod \
CGO_CFLAGS="-I/lib" \
CGO_CFLAGS="-I/lib -O2" \
CGO_CFLAGS_ALLOW=".*" \
CGO_LDFLAGS="-L/lib" \
BLST_PORTABLE=${BLST_PORTABLE} \
# Override the wasmvm library path to use our musl version
LD_LIBRARY_PATH=/lib

Expand Down Expand Up @@ -50,6 +53,7 @@ COPY decentralized-api/. .
# ARG LDFLAGS
RUN --mount=type=cache,id=go-build-cache3,target=/root/.cache/go-build \
--mount=type=cache,id=go-mod-cache3,target=/go/pkg/mod \
if [ "$BLST_PORTABLE" = "1" ]; then export CGO_CFLAGS="$CGO_CFLAGS -D__BLST_PORTABLE__"; fi; \
CGO_ENABLED=1 CC=gcc \
go build -mod=readonly -tags muslc -ldflags "$LDFLAGS" \
-o ./build/dapi \
Expand All @@ -59,6 +63,7 @@ RUN --mount=type=cache,id=go-build-cache3,target=/root/.cache/go-build \
RUN --mount=type=cache,id=go-build-cache3,target=/root/.cache/go-build \
--mount=type=cache,id=go-mod-cache3,target=/go/pkg/mod \
cd /app/inference-chain && \
if [ "$BLST_PORTABLE" = "1" ]; then export CGO_CFLAGS="$CGO_CFLAGS -D__BLST_PORTABLE__"; fi; \
CGO_ENABLED=1 CC=gcc \
go build -mod=readonly -tags muslc -ldflags "-X github.com/cosmos/cosmos-sdk/version.Name=inference-chain -X github.com/cosmos/cosmos-sdk/version.AppName=inference-chaind" \
-o ./build/inferenced ./cmd/inferenced/main.go \
Expand Down
4 changes: 3 additions & 1 deletion decentralized-api/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
COMMIT := $(shell git log -1 --format='%H')

VERSION ?= $(shell git describe --always)
BLST_PORTABLE ?= 0
SET_LATEST ?= 0
SET_LATEST := $(shell if [ "$(SET_LATEST)" = "1" ]; then echo 1; else echo 0; fi)

Expand All @@ -29,6 +30,7 @@ define DOCKER_BUILD
--build-arg BUILD_FLAGS="$(BUILD_FLAGS)" \
--build-arg GOOS=$(GOOS) \
--build-arg GOARCH=$(GOARCH) \
--build-arg BLST_PORTABLE=$(BLST_PORTABLE) \
-f $(DOCKER_FILE) \
.. \
-t $(DOCKER_TAG)
Expand Down Expand Up @@ -164,4 +166,4 @@ package:
build/$$os/$$arch/decentralized-api; \
fi; \
done; \
done
done
22 changes: 12 additions & 10 deletions decentralized-api/apiconfig/config_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,19 @@ func LoadConfigManagerWithPaths(configPath, sqlitePath, nodeConfigPath string) (
return nil, err
}

err = manager.migrateDynamicDataToDb(ctx)
migrated, err := manager.migrateDynamicDataToDb(ctx)
if err != nil {
log.Printf("Error migrating dynamic data to DB: %+v", err)
return nil, err
}

if err = manager.Write(); err != nil {
log.Printf("Error writing config: %+v", err)
return nil, err
if migrated {
if err = manager.Write(); err != nil {
log.Printf("Error writing config: %+v", err)
return nil, err
}
logging.Info("Saved static config after initial migration", types.Config)
}
log.Printf("Saved static config after load")

// Hydrate in-memory dynamic state from DB once
if err := manager.HydrateFromDB(context.Background()); err != nil {
Expand Down Expand Up @@ -635,15 +637,15 @@ func parseInferenceNodesFromNodeConfigJson(nodeConfigPath string) ([]InferenceNo
return newNodes, nil
}

func (cm *ConfigManager) migrateDynamicDataToDb(ctx context.Context) error {
func (cm *ConfigManager) migrateDynamicDataToDb(ctx context.Context) (bool, error) {
if err := cm.ensureDbReady(ctx); err != nil {
return err
return false, err
}
// Only migrate once, gated by a KV flag
var migrated bool
if ok, err := KVGetJSON(ctx, cm.sqlDb.GetDb(), kvKeyConfigMigrated, &migrated); err == nil && ok && migrated {
logging.Info("Config migration already completed. Skipping", types.Config)
return nil
return false, nil
}
config := cm.currentConfig
// If YAML indicates nodes were already merged historically, persist the flag so LoadNodeConfig skips
Expand All @@ -653,7 +655,7 @@ func (cm *ConfigManager) migrateDynamicDataToDb(ctx context.Context) error {
// Nodes: upsert unconditionally (idempotent)
if err := WriteNodes(ctx, cm.sqlDb.GetDb(), config.Nodes); err != nil {
logging.Error("Error writing nodes to DB", types.Config, "error", err)
return err
return false, err
}

// Per-key idempotent migrations: only populate if missing
Expand Down Expand Up @@ -708,7 +710,7 @@ func (cm *ConfigManager) migrateDynamicDataToDb(ctx context.Context) error {

// Mark migration as done
_ = KVSetJSON(ctx, cm.sqlDb.GetDb(), kvKeyConfigMigrated, true)
return nil
return true, nil
}

// HydrateFromDB loads dynamic fields from DB into memory ONCE during startup.
Expand Down
26 changes: 26 additions & 0 deletions decentralized-api/apiconfig/config_manager_migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,29 @@ nodes:
require.Contains(t, ids, "json-node", string(b))
require.NotContains(t, ids, "yaml-node2", string(b))
}

func TestConfigNotRewrittenOnSecondLoad(t *testing.T) {
tmp := t.TempDir()
yaml := `api:
port: 8080
chain_node:
url: http://localhost:26657
signer_key_name: test`
cfgPath := writeTempFile(t, tmp, "config.yaml", yaml)
dbPath := filepath.Join(tmp, "test.db")

mgr1, err := apiconfig.LoadConfigManagerWithPaths(cfgPath, dbPath, "")
require.NoError(t, err)
require.NoError(t, mgr1.FlushNow(context.Background()))

stat1, err := os.Stat(cfgPath)
require.NoError(t, err)

mgr2, err := apiconfig.LoadConfigManagerWithPaths(cfgPath, dbPath, "")
require.NoError(t, err)
require.NoError(t, mgr2.FlushNow(context.Background()))

stat2, err := os.Stat(cfgPath)
require.NoError(t, err)
require.Equal(t, stat1.ModTime(), stat2.ModTime())
}
Loading
Loading