23675 Commits

Author SHA1 Message Date
Alex Ant 3406fd525f fix(chain): lazy-init builtin registries — global static crashed leap-util (#10)
The genesis registry was a namespace-scope static whose initializer parses
public_key_type values; fc's own static state is not guaranteed to exist at
that point, and every leap-util invocation (even 'version client') aborted
with fc::assert_exception before main() — classic static init order fiasco.
nodeos was unaffected only because the linker never pulls the unused object
file out of the static library.

Both builtin registries (genesis, historical exceptions) now use function-
local statics built on first use.

Co-authored-by: coopops <coopos@coopenomics.world>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
v5.3.3
2026-06-11 00:41:08 +05:00
Alex Ant 82e399a2ca feat(leap-util): built-in genesis registry — 'genesis print/list' subcommands (#9)
Bootstrapping a fresh node used to require an externally hosted genesis.json;
lose the file and you cannot sync. The canonical genesis states of known
Coopenomics chains (mainnet, testnet) are now compiled into the binary and
reproducible from the package alone:

  leap-util genesis list                      # names + chain ids
  leap-util genesis print mainnet > genesis.json

Each entry only overrides initial_key — the production initial_timestamp and
chain_config values are already the compile-time defaults of genesis_state.
The default EOSIO_ROOT_KEY is intentionally untouched, so dev forks and the
docker-hub harness keep their well-known dev key; one build serves mainnet,
testnet and dev (a config-time root key change would have forked every dev
setup, and shipping per-network builds was rejected outright).

Unit test pins both registry chain ids to the canonical values, proving every
hashed genesis field is correct, and pins the dev default to NOT equal any
production genesis.

Co-authored-by: coopops <coopos@coopenomics.world>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 22:17:26 +05:00
Alex Ant 2ef58997e1 fix(chain): extend mainnet exception windows through setcode block 113275717 (#8)
Empirical full replay on 2026-06-10 proved the incident model wrong in one
detail: onblock on the buggy build THREW on every block (it did not merely
skip receipt recording), and recovery happened in-band — block 113275717
carries the eosio::setcode that replaced the system contract, produced 0.5s
after the last zero-mroot block with no BP restart. Onblock was still failing
while 113275717 itself was produced, so its canonical action_mroot covers
only the setcode receipt; a replay that runs onblock there computes a
two-receipt mroot and fails "Block ID does not match".

Extend both builtin windows (action_mroot bypass + onblock skip) from
113275716 to 113275717 inclusive. The 2395 in-window blocks replay
bit-identical to the canonical chain (zero mroot, matching block ids — the
mroot bypass never even fires); user transactions inside the window execute
normally.

Co-authored-by: coopops <coopos@coopenomics.world>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
v5.3.2
2026-06-10 15:11:49 +05:00
Alex Ant b94c791b10 feat(chain): v5.3.1 — onblock skip + non-zero mroot bypass + builtin registry (#7)
Three coupled mechanisms in chain_historical_exceptions so archival nodes can
replay coopenomics mainnet past the 2026-05-11 v5.2.0-dev incident:

- chain_historical_exceptions gains onblock_skip_windows and
  suppressed_activations vectors; both are optional in the JSON form so v5.3.0
  files keep parsing.
- apply_block bypass no longer requires action_mroot == 0 inside a window —
  any divergent mroot is accepted when every other header field matches.
  Needed because a sound replay computes a non-zero mroot in the dirty window
  (onblock works) while the canonical chain stored zero.
- start_block skips the implicit onblock transaction inside any configured
  window. Without this the chainbase (block_summary_object etc.) mutated by
  onblock diverges from canonical state and every later block fails to
  validate, defeating the mroot bypass.
- trigger_activation_handler can be suppressed per feature_digest via the
  registry — guards against future incidents where a marked-activated feature
  must not run its handler during replay.
- New chain_exceptions_builtin.cpp ships a compiled-in registry keyed by
  chain_id; for coopenomics mainnet it carries action_mroot + onblock-skip
  windows [113273322..113275716]. Operators no longer need to distribute a
  separate JSON file; the .deb is self-contained. File option still wins
  per-node when set.

Co-authored-by: coopops <coopos@coopenomics.world>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
v5.3.1
2026-06-04 10:12:24 +05:00
Alex Ant c7cd80af29 Merge pull request #6 from coopenomics/chore/bump-version-5.3.0
chore(release): bump CMake VERSION to 5.3.0
v5.3.0
2026-06-03 15:32:57 +05:00
coopops 1586a2e0e0 chore(release): bump CMake VERSION to 5.3.0
CMakeLists.txt still hardcoded 5.2.0, so v5.3.0 tag produced
coopos_5.2.0-*.deb. dpkg -i over installed 5.2.0 would no-op.
Bump VERSION_MINOR=3 so artifact matches tag.
2026-06-03 10:32:35 +00:00
Alex Ant 31fd09ba00 Merge pull request #5 from coopenomics/fix/test-json-to-string-signature
fix(unittests): drop json_roundtrip — fc::json::to_string template requires deadline
2026-06-03 13:04:31 +05:00
coopops 1ab8b51a21 fix(unittests): drop json_roundtrip test, fc::json::to_string requires deadline
The template overload fc::json::to_string<T>(...) in this fork takes the
deadline argument without a default (only the variant overload has a
default), so the one-arg call inside json_roundtrip would not compile:

  error: no matching function for call to
    'fc::json::to_string(eosio::chain::chain_historical_exceptions&)'
  note: candidate expects 4 arguments, 1 provided

JSON round-trip is already exercised indirectly by every remaining test
case — each writes the file via fc::json::to_pretty_string (template
overload with deadline default) and the controller reads it back via
fc::json::from_file<T>() in the loader.
2026-06-03 08:04:14 +00:00
Alex Ant ad0458c5b2 Merge pull request #4 from coopenomics/fix/chain-exceptions-default-ctor
fix(chain): default-construct chain_id in chain_historical_exceptions
2026-06-03 12:26:17 +05:00
coopops 8790ed487c fix(chain): default-construct chain_id in chain_historical_exceptions
chain_id_type has a private default constructor (only friend classes like
controller_impl and fc::variant::as can default-construct one). Relying on
the implicit default ctor in chain_historical_exceptions therefore made it
not default-constructible, which broke both the controller_impl member init
and fc::variant::as<chain_historical_exceptions>() in the JSON loader:

  error: use of deleted function
    'eosio::chain::chain_historical_exceptions::chain_historical_exceptions()'
  note: 'eosio::chain::chain_id_type::chain_id_type()' is private

Provide an explicit default ctor that initialises chain_id via the public
empty_chain_id() factory. Loader then overwrites it with the value parsed
from the JSON file and asserts equality with self.get_chain_id().
2026-06-03 07:26:02 +00:00
Alex Ant e912250950 Merge pull request #3 from coopenomics/release/5.3.0
feat(chain): chain-historical-exceptions registry for v5.2.0 dirty window
2026-06-03 11:20:34 +05:00
coopops de24cd822e feat(chain): chain-historical-exceptions registry for action_mroot bypass
Adds a generic per-chain exception mechanism that lets a controller skip
the producer_block_id != ab._id assert in apply_block when the only
header divergence is a known historical action_mroot=0 inside a declared
block-number window for the matching chain_id.

Motivation: on 2026-05-11 the mainnet Коопеномикс BP briefly ran a dev
build (v5.2.0-dev-294edf3b8) that did not register the on_activation
handler for ASSERT_RECOVER_KEY_ACCOUNT (id=24). For ~20 minutes (blocks
113273322..113275716) onblock did not register intrinsics,
_action_receipt_digests was empty and finalized action_mroot was the
zero digest. The window is now permanently irreversible. Any current
binary refuses to replay past block 113273322 with
block_validate_exception, so new full-history archive nodes / fresh BPs
/ --hard-replay-blockchain on mainnet are blocked.

Design (see exception-notes.md):
- New struct chain_historical_exceptions { chain_id, windows[] }
  loaded from a JSON file path supplied via the new config option
  chain-historical-exceptions. Absent / empty file => no change in
  behavior, strict upstream Antelope validation. Forks and subnets
  reusing this codebase without supplying a file are unaffected.
- Loader fires from controller_impl::init() right after
  protocol_features.init(db) (where self.get_chain_id() is valid) and
  EOS_ASSERTs that the file's chain_id matches the running chain — so
  the mainnet exception file cannot accidentally be applied to a
  different chain.
- Bypass site is the existing producer_block_id != ab._id branch in
  apply_block. Bypass fires only when all three hold: block_num is
  inside a declared window, b->action_mroot is strictly the zero
  digest, and a new other_header_fields_match helper confirms every
  other header field (timestamp, producer, confirmed, previous,
  transaction_mroot, schedule_version, new_producers,
  header_extensions) matches the locally-assembled block. Any other
  header divergence still throws block_validate_exception as before.
- Every bypass application is logged via wlog with the configured
  reason for forensics.

The data file for mainnet Коопеномикс is shipped separately (lives in
the playbooks repo, deployed to /etc/coopos/exceptions/) so the data
never leaks into forks that simply pull this codebase.

Unit tests cover JSON round-trip, chain_id mismatch -> startup refusal,
in-window action_mroot=0 -> bypass accepts, out-of-window -> rejected,
and in-window-but-other-field-altered -> rejected.

Refs: incident 2026-05-11, coopos commit 2c23b8108 (root-cause fix that
arrived too late for the dirty window).
2026-06-03 06:19:06 +00:00
coopops fa8502eccc chore: add CLAUDE.md with project-scoped agent notes
Перенёс из общей auto-memory в репо: миграции версий, snapshot-vs-full-resync, Dockerfile.publish target. Часть реорганизации памяти агента по проектам.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 16:25:34 +00:00
coopops 2c23b81082 fix(protocol_feature): register on_activation handler for ASSERT_RECOVER_KEY_ACCOUNT
Previous commit declared template specialization but missed
set_activation_handler<>() call in controller_impl ctor — so the handler
was never inserted into protocol_feature_activation_handlers map and
trigger_activation_handler() returned silently on feature activation.

Result: feature got marked activated in state, but assert_recover_key_account
was not added to whitelisted_intrinsics. Existing chains with the old build
must re-init from a pre-activation snapshot to get the handler to run during
replay.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v5.2.0
2026-05-11 14:13:17 +00:00
coopops ed23103d79 feat(protocol_feature): ASSERT_RECOVER_KEY_ACCOUNT builtin (id=24)
Adds new builtin protocol feature that whitelists assert_recover_key_account
intrinsic on activation. Required for existing chains (testnet/mainnet) where
this intrinsic is not in whitelisted_intrinsics state — they cannot accept
WASM that imports env.assert_recover_key_account until the feature is
preactivated + activated via eosio::activate.

on_activation handler is idempotent: на свежем genesis intrinsic уже
добавлен через genesis_intrinsics, на действующих цепочках добавляется
здесь.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 12:20:52 +00:00
coopops 71cd13cae1 docs(README): production genesis.json + инструкция запуска ноды на mainnet
Добавлен новый раздел "Запуск ноды на основной сети Кооперативной Экономики":
- embedded production genesis.json с initial_key EOS7Tjq... (mainnet chain_id 6e37f9ac...);
- объяснение почему дефолтный EOSIO_ROOT_KEY из бинарника не подходит и нужен явный --genesis-json при первом запуске на пустой data-dir;
- пошаговая процедура полного ресинка через --genesis-json (stop → wipe data → подложить genesis → флаг в unit → start → снять флаг);
- альтернативная процедура быстрого старта через --snapshot.

TOC обновлён (пункт 5).
2026-05-11 11:45:19 +00:00
coopops 111696cc77 build: убрать хардкод VERSION_SUFFIX=dev
Раньше каждая сборка получала имя `coopos_5.2.0-dev-...deb` и
`coopos-dev_5.2.0-dev-...deb` — слово «dev» в имени файла означало
одновременно (а) pre-release-суффикс версии и (б) component-имя
второго пакета. Это путало: «у одного dev в начале, у другого
в конце».

VERSION_SUFFIX переведён в CACHE STRING с пустым default. Релизный
билд даёт чистое `5.2.0`. При необходимости pre-release —
`cmake -DVERSION_SUFFIX=rc1 …`.

Имена пакетов после правки:
  - coopos_5.2.0-ubuntu22.04_amd64.deb       (runtime)
  - coopos-dev_5.2.0-ubuntu22.04_amd64.deb   (headers, EosioTester)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 07:55:55 +00:00
coopops 5bb051f9ad fix(intrinsics): переместить assert_recover_key_account в конец таблиц — ABI compat
Вставка нового intrinsic в середину intrinsic_mapping/genesis_intrinsics/eos-vm
регистраций сдвинула индексы всех последующих host functions на 1. Старые wasm
(включая eosio.system, скомпилированный до v5.2.0) по импортам "env.X" попадают
на новые индексы, и context-aware вызов из onblock приземляется на
context-free-only assert_recover_key_account → REJECT каждого блока с
"this API may only be called from context_free apply".

Перенос в конец всех трёх таблиц восстанавливает порядок индексов для ранее
существовавших intrinsics. Сам метод остаётся доступным с новым (большим)
индексом — будущие wasm-сборки увидят его как обычно.
2026-05-11 07:53:19 +00:00
coopops 68339a64f5 fix(ci): publish runtime stage explicitly, not scratch deb stage
Без `target: runtime` buildx публиковал последнюю стадию `deb`
(scratch с .deb файлами), а не runnable runtime. Из-за этого
dicoop/blockchain:latest и :v5.2.0 на Hub были неисполнимым
dist-артефактом.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 17:22:53 +00:00
coopops 0d7d6c135b feat(leap-util): add 'snapshot from-json' subcommand
Симметричный аналог 'snapshot to-json': читает JSON-снапшот через
istream_json_snapshot_reader (уже реализован в libraries/chain/snapshot.cpp,
строки 343-433) и пишет binary через ostream_snapshot_writer.

Pipeline для форка прод-ноды:
  leap-util snapshot to-json -i snapshot.bin -o s.json
  jq '<подмена ключей и producer schedule>' s.json > s.patched.json
  leap-util snapshot from-json -i s.patched.json -o snapshot-fork.bin
  nodeos --snapshot snapshot-fork.bin
2026-05-05 10:53:11 +00:00
coopops 4427bdf235 fix(ci): drop tweak-deb.sh — incompatible with modern dpkg
cpack on Ubuntu 22.04 produces control.tar.zst, but the leap-era
tools/tweak-deb.sh hardcodes 'ar x control.tar.gz', which fails with
'tar: Unexpected EOF in archive'.

The tweak is only a cosmetic libc-dep cleanup; without it the .deb
files are still valid. Drop the call.
2026-05-02 05:44:23 +00:00
coopops d38a945269 fix(ci): keep LICENSE/README/docs in build context
CMakeLists.txt reads LICENSE via configure_file at line 219; excluding
it from .dockerignore caused the build to fail with:
  CMake Error: File /blockchain/LICENSE does not exist.

Be conservative — only exclude things definitely unused by cmake:
build artefacts, logs, CI configs, and images/ (logos).
2026-05-01 17:04:52 +00:00
coopops 7172b51e75 ci(docker): split cpack into separate RUN for cache stability
Keeps the heavy blockchain build cached even when cpack/tweak logic
changes. The split is at the RUN boundary, no functional difference.
2026-05-01 16:54:02 +00:00
coopops 33b1179e39 feat(ci): build & publish .deb packages to GitHub Release
Adds DEB packaging to the same docker-publish workflow:

Builder stage (Dockerfile.publish):
- Pass -DENABLE_LEAP_DEV_DEB=ON to cmake. This activates component-based
  install rules and lets cpack -G DEB produce two debs:
    * coopos_<ver>-ubuntu22.04_amd64.deb       (runtime: nodeos/cleos/...)
    * coopos-dev_<ver>-ubuntu22.04_amd64.deb   (headers, libs, cmake
      config — required to build smart contracts and run mono tests
      that depend on find_package(leap))
- Run cpack -G DEB after make install
- Apply tools/tweak-deb.sh to fix overly-strict libc deps in control
- Stage debs at /out/deb/ for the next stage to export

New 'deb' stage (FROM scratch):
- Exports only the .deb files. Used by CI to extract packages without
  pulling the full builder image.

Workflow:
- New step runs buildx with --target deb --output type=local to pull
  the .deb files onto the runner. This reuses the same GHA cache scope
  as the runtime image, so on a tag with cache-hit it adds only minutes.
- On tag pushes, .deb files are attached to the GitHub Release via
  softprops/action-gh-release@v2 (tag is created if missing).
- Always upload .deb as a workflow artifact too (30 days retention),
  so manual runs still produce downloadable packages.
- permissions: contents: write — needed to write to releases.
2026-05-01 16:53:30 +00:00
coopops d156742a38 ci(docker): cache stability — add .dockerignore + shared GHA scope
- .dockerignore excludes .cicd/, .github/, docs/, tutorials/, images/,
  README.md, CONTRIBUTING.md, LICENSE from the coopos build-context.
  Changes to CI/docs no longer invalidate the heavy COPY --from=coopos
  layer, so subsequent builds become true cache-hits.

- cache-from/to now use scope=docker-publish (instead of default per-ref
  scope). GHA cache is reused across different tags (v5.2.0, v5.2.1, …)
  and across branches, so a new tag is no longer a cold rebuild.
2026-05-01 15:26:09 +00:00
Alex Ant 17278c2dcd chore(ci): remove legacy AntelopeIO/leap workflows and infra (#2)
These workflows depended on AntelopeIO infrastructure that is not
available to coopenomics:
- self-hosted runners enf-x86-{beefy,hightier,midtier,lowtier}
  and Leap-Perf-* (build.yaml, build_base.yaml, perf workflows)
- AntelopeIO/platform-cache-workflow + .cicd/platforms images
- AntelopeIO/issue-project-labeler-workflow + ENFCIBOT secrets
  (label_new_issues.yaml)
- ENF Jira instance (jiraIssueCreator.yml)
- artifacts produced by build.yaml (release.yaml depended on them)

Removed:
- .github/workflows/build.yaml
- .github/workflows/build_base.yaml
- .github/workflows/release.yaml          (replaced by docker-publish)
- .github/workflows/pinned_build.yaml     (was a stub)
- .github/workflows/performance_harness_run.yaml
- .github/workflows/ph_backward_compatibility.yaml
- .github/workflows/jiraIssueCreator.yml
- .github/workflows/label_new_issues.yaml
- .cicd/platforms/                        (only used by removed workflows)
- .cicd/defaults.json                     (only read by build.yaml)
- tools/reproducible.Dockerfile           (only used by build.yaml)
- .github/actions/parallel-ctest-containers/

Kept and active:
- .github/workflows/docker-publish.yaml   (slim Docker Hub publish)
- .github/workflows/docs-updater.yaml     (triggers docs deploy)
- .github/workflows/submod.yaml           (cheap submodule sanity check)
- .cicd/Dockerfile.publish                (used by docker-publish)
- tools/tweak-deb.sh                      (kept for upcoming .deb packaging)

Co-authored-by: coopops <coopos@coopenomics.world>
2026-05-01 20:22:37 +05:00
coopops 716ee56446 fix(ci): mkdir -p /cdt before symlink in runtime stage
Previous commit dropped the mkdir, breaking the runtime build:
  ln: failed to create symbolic link '/cdt/build': No such file or directory
2026-05-01 13:47:02 +00:00
coopops 21a91e58b3 ci(docker): add gcc/g++/libz3-4 to runtime, symlink /cdt/build
- mono contracts CMakeLists.txt does project(coopenomics) without
  LANGUAGES, requiring host C/CXX compilers; install gcc + g++
- cdt-cpp depends on libz3.so.4 at runtime (Z3 solver in clang-9)
- CDTWasmToolchain.cmake hardcodes /cdt/build/{bin,include,lib} from
  the source build directory, replace narrow lib/cmake symlink with
  /cdt/build -> /usr/local/cdt covering all needed subpaths

Verified locally: components/contracts test contract builds to
test.wasm + test.abi inside a clean slim image.
2026-05-01 12:03:00 +00:00
Alex Ant 9ad300c68f ci: Docker Hub build & publish for dicoop/blockchain (#1)
* ci: add multi-stage Dockerfile.publish for Docker Hub image

Multi-stage Dockerfile that builds blockchain (coopos) and CDT in a
builder stage, then copies only /usr/local into a slim runtime stage.

Will be used by docker-publish workflow to publish
dicoop/blockchain:<tag> on every v* tag.

* ci: add docker-publish workflow

Triggers on v* tags and via workflow_dispatch (cdt-ref/version-tag/
push-latest inputs). Builds with .cicd/Dockerfile.publish on
ubuntu-latest with BuildKit GHA cache, pushes to Docker Hub as
dicoop/blockchain:<tag> and :latest.

---------

Co-authored-by: coopops <coopos@coopenomics.world>
2026-05-01 14:41:44 +05:00
Alex Ant 294edf3b84 каллибровка config.hpp для выхода на изначальные параметры запуска 2025-10-23 18:59:05 +05:00
Alex Ant 8fd34abdd8 change default genesis timestamp to 2024-07-01T10:00:00 2025-10-23 18:06:54 +05:00
Alex Ant a2692003d5 bump version 2025-10-15 21:50:44 +05:00
Alex Ant 20eca25f91 метод assert_recover_key_account для проверки принадлежности подписи к аккаунту на контрактах 2025-10-15 01:25:58 +05:00
Alex Ant 4b3a71cf0a update README v5.1.0 2025-10-10 17:44:20 +05:00
Alex Ant b04a251cdd LICENCE 2025-10-10 17:41:04 +05:00
Alex Ant 44f1a76d98 LEAP -> COOPOS rebranding 2025-10-10 17:40:42 +05:00
Alex Ant 26e43fbc85 workflow and api specification change 2025-08-27 14:26:05 +05:00
Alex Ant a6ccb8b183 rent RAM temporary 2025-08-27 13:25:55 +05:00
Areg Hayrapetian 92b6fec5e9 Merge pull request #2414 from AntelopeIO/unsupported_message
Add note to README that Leap is no longer supported
2024-11-13 11:08:48 -08:00
Areg Hayrapetian b0efd9f782 Add note to README that Leap is no longer supported. 2024-11-13 10:26:35 -08:00
Matt Witherspoon 99ee7a7aff Merge pull request #2390 from AntelopeIO/submod_token
use github provided token for git in submodule regression check
2024-04-10 12:02:17 -04:00
Dark Sun b7dd04e2eb update genesis_intrinsics 2024-04-10 18:34:37 +03:00
Dark Sun c1925d6934 update CMakeLists and Dockerfile 2024-04-10 16:30:25 +03:00
Dark Sun 873dac1e64 Dockerfile update #2 2024-04-10 16:23:13 +03:00
Dark Sun b470caa066 update Dockerfile #1 2024-04-10 16:15:36 +03:00
Dark Sun f7cc61dd31 Dockerfile 2024-04-10 16:14:00 +03:00
Matt Witherspoon 9924b77166 use github provided token for submodule check 2024-04-09 23:40:32 -04:00
Dark Sun 9c39eec6da add get_account_ram_usage method 2024-04-09 18:10:44 +03:00
Matt Witherspoon eabddaebeb Merge pull request #2382 from AntelopeIO/remove_lots_execbit
remove executable bit from a lot of files
2024-04-05 10:42:18 -04:00
Kevin Heifner 3dee3557aa Merge pull request #2377 from AntelopeIO/trace-api-no-sync
TraceAPI: Remove sync() to improve performance
2024-04-04 21:40:47 -05:00