Skip to content

feat(models): флаги ledger-объектов, гвард по LedgerFormats.h и покрытие DynamicMPT (10.11.0.0) - #71

Open
Platonenkov wants to merge 2 commits into
devfrom
claude/node-3-2-1-updates-901277
Open

feat(models): флаги ledger-объектов, гвард по LedgerFormats.h и покрытие DynamicMPT (10.11.0.0)#71
Platonenkov wants to merge 2 commits into
devfrom
claude/node-3-2-1-updates-901277

Conversation

@Platonenkov

@Platonenkov Platonenkov commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator

Зачем

Разбор состава грядущего релиза ноды 3.3.0 по моделям SDK показал, что протокол покрыт полностью — поля, типы транзакций, ledger-объекты и коды результата совпадают с 3.3.0-rc1 один в один — кроме двух мест: DynamicMPT без интеграционного покрытия и флаги ledger-объектов, которые не сверялись с протоколом ничем.

Второе оказалось системной проблемой. LedgerFormats.h — единственное место, где протокол объявляет, какие lsf-флаги принадлежат какому ledger-объекту (definitions.json несёт коды полей и типы объектов, но не значения флагов). Против него не стоял ни один тест, и пропущенный флаг не давал симптома: безымянный бит всё равно приходит в модель числом, теряется только возможность проверить его по имени. Так lsfMPTAMM прожил несколько релизов.

Что сделано

Флаги ledger-объектов

Пофайловый диф всех enum'ов против тега 3.3.0-rc1 нашёл четыре пробела:

  • MPTokenIssuanceFlags + MPTCanHoldConfidentialBalance (0x80) — вводит ConfidentialTransfer. Остальная поддержка амендмента уже полная (транзакции 85–89, IssuerEncryptionKey/AuditorEncryptionKey, ConfidentialOutstandingAmount), не хватало только имени у флага.
  • MPTokenFlags + lsfMPTAMM (0x4) — пробел старше ConfidentialTransfer: флаг есть уже в 3.2.1. AMMCreate ставит его вместе с lsfMPTAuthorized, неявно авторизуя MPT-актив для псевдо-аккаунта AMM.
  • LOLoan.Flags — у объекта Loan вообще не было свойства Flags (нет его и в BaseLedgerEntry), то есть lsfLoanDefault/lsfLoanImpaired/lsfLoanOverpayment не читались типизированной моделью никак: статус дефолта и impairment займа был ненаблюдаем. Добавлено как LoanFlags?.
  • SignerListFlags и DirectoryNodeFlags — новые enum'ы. Сами свойства Flags остаются uint (смена типа была бы breaking), enum'ы дают именованные константы вместо магических чисел. Заодно исправлен ложный комментарий у LODirectoryNode.Flags, утверждавший, что протокол не определяет флагов для этого объекта.

TestULedgerFlagsConformance — гвард против повторения

Ledger-аналог существующего TestUTxFormatConformance:

  • Tests/Xrpl.Tests/Fixtures/LedgerFormats.h вендорен байт-в-байт и пиннут по sha в .ref — перепроверяется обычным curl … | diff. Пин, а не живая ветка, по той же причине, что и у transactions.macro: отслеживание upstream-дрейфа — работа protocol-watch, а сетевой тест краснел бы по релизному расписанию Ripple, а не по нашему.
  • RippledLedgerFlags парсит макросы LEDGER_OBJECT/LSF_FLAG и падает громко: незнакомый вариант LSF_FLAG* или разбор, давший меньше 10 объектов / 50 флагов, бросает исключение вместо того, чтобы оставить тест зелёным на пустой таблице.
  • Диф идёт в обе стороны (флаг есть у rippled и нет в enum; флаг есть в enum и отсутствует у rippled), и каждый флагованный объект обязан быть зарегистрирован против модельного enum — новый ledger-объект роняет сборку, а не пропускается молча. tf*-члены, живущие в одном enum с ledger-флагами (OfferFlags.tfInnerBatchTxn), и нулевые члены исключены по правилу.
  • Сопоставление имён нормализует префиксы lsf/lsmf/tmf, поэтому lsfMPTLockedMPTLocked, а lsmfMPTCanEnableCanLock у rippled ≡ tmfMPTCanEnableCanLock у нас (rippled сам делает tmfX = lsmfX в TxFlags.h).

Гвард проверен мутациями, а не только тем, что он зелёный. Три ветки, каждая даёт внятное падение:

мутация сообщение
значение 0x80 → 0x81 MPTokenIssuance.lsfMPTCanHoldConfidentialBalance: rippled 0x00000080, MPTokenIssuanceFlags 0x00000081
удалён lsfMPTAMM MPToken.lsfMPTAMM (0x00000004): declared by rippled, missing from MPTokenFlags
Loan убран из реестра Loan: declares 3 flag(s) in LedgerFormats.h but no model enum is registered for it

DynamicMPT (XLS-94)

AmendmentGuard получил id амендмента (совпал с тем, что generate-amendments.sh уже пишет в [amendments] nightly-стенда), TestIDynamicMPT — 4 теста, каждый читает результат из ledger-объекта, а не из EngineResult:

  1. MutableFlags с MPTokenIssuanceCreate доезжают в LOMPTokenIssuance без искажения;
  2. MPTokenIssuanceSet меняет TransferFee и MPTokenMetadata, не переписывая MutableFlags;
  3. tmfMPTSetCanLock поднимает lsfMPTCanLock на issuance, созданном без этой возможности;
  4. мутация без разрешения отбивается tecNO_PERMISSION, метаданные в ledger остаются прежними.

Сценарии выверены по транзактору src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp @ 3.3.0-rc1, а не по документации: отсюда tfMPTCanTransfer на создании во втором тесте — preclaim требует lsfMPTCanTransfer уже установленным, включение его той же транзакцией правило не удовлетворяет.

Проверка

Прогон Результат
nightly-стенд (3.3.0-b1), TestILoan|TestIDynamicMPT|TestIMPToken 41/41 passed
CI-стенд (xrpld 3.2.0), TestIDynamicMPT 4 skipped через гвард, exit 0
Юнит-тесты (TestU) 869/869 passed
Сборка решения 0 ошибок

Значение 0x80 подтверждено не только по заголовку, но и на живом объекте: MPTokenIssuanceSet с MutableFlags = tmfMPTSetCanHoldConfidentialBalance (0x40) переводит issuance из Flags = 0 в Flags = 128.

Версия

Xrpl поднят 10.10.0.0 → 10.11.0.0 — minor, потому что в публичном API только добавления (новые члены enum, новые enum-типы, новое свойство LOLoan.Flags); ничего не удалено и не переименовано, типы существующих свойств не менялись. Base-пакеты (Xrpl.AddressCodec, Xrpl.BinaryCodec, Xrpl.Keypairs) не затронуты — git diff origin/dev...HEAD -- Base/ пуст, поэтому их версии остаются как есть. CHANGES.md дополнен разделом 10.11.0.0.

…amicMPT

Модели MPT отставали от rippled по флагам ledger-объектов, а DynamicMPT
(XLS-94) не имел ни гварда, ни интеграционных тестов: поля MutableFlags в
моделях были, но против ноды никогда не проверялись.

* MPTokenIssuanceFlags + MPTCanHoldConfidentialBalance (0x80) — вводит
  ConfidentialTransfer; остальная поддержка амендмента уже полная
  (транзакции 85-89, IssuerEncryptionKey/AuditorEncryptionKey,
  ConfidentialOutstandingAmount), не хватало только имени у флага
* MPTokenFlags + lsfMPTAMM (0x4) — пробел старше: флаг есть уже в 3.2.1.
  AMMCreate ставит его вместе с lsfMPTAuthorized, неявно авторизуя MPT-актив
  для псевдо-аккаунта AMM (src/libxrpl/tx/transactors/dex/AMMCreate.cpp)
* AmendmentGuard + DynamicMPT; id совпал с тем, что generate-amendments.sh
  уже кладёт в [amendments] nightly-стенда
* TestIDynamicMPT — 4 теста, каждый читает результат из ledger-объекта:
  MutableFlags с Create доезжают в LOMPTokenIssuance; MPTokenIssuanceSet
  меняет TransferFee и MPTokenMetadata, не переписывая MutableFlags;
  tmfMPTSetCanLock поднимает lsfMPTCanLock на issuance, созданном без него;
  мутация без разрешения отбивается tecNO_PERMISSION, а метаданные в ledger
  остаются прежними

Сценарии выверены по транзактору rippled 3.3.0-rc1
(src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp), а не по документации:
отсюда tfMPTCanTransfer на создании — preclaim требует lsfMPTCanTransfer уже
установленным, включение его той же транзакцией правило не удовлетворяет.

Проверено: nightly-стенд (3.3.0-b1, DynamicMPT enabled) — 4/4 passed;
CI-стенд (xrpld 3.2.0) — 4 skipped через гвард, exit 0; MPT-регрессия 28/28,
юнит-тесты 867/867. Значение 0x80 подтверждено на живом объекте:
MPTokenIssuanceSet с MutableFlags=0x40 даёт Flags=128.
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b409fcd8-eecb-44ab-81b7-6f3d63dd489d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

… дрейфа

LedgerFormats.h — единственное место, где протокол объявляет, какие lsf-флаги
принадлежат какому ledger-объекту (definitions.json несёт коды полей и типы
объектов, но не значения флагов). Против него не стоял ни один тест, поэтому
пропущенный флаг не давал симптома: безымянный бит всё равно приходит в модель
числом, теряется только возможность проверить его по имени. Так lsfMPTAMM
прожил несколько релизов. Пофайловый диф всех enum'ов против тега 3.3.0-rc1
нашёл четыре пробела.

* MPTokenIssuanceFlags + MPTCanHoldConfidentialBalance (0x80) — от
  ConfidentialTransfer; значение подтверждено на живом объекте
* MPTokenFlags + lsfMPTAMM (0x4) — пробел старше, флаг есть уже в 3.2.1
* LOLoan.Flags — у объекта Loan вообще не было свойства Flags (нет его и в
  BaseLedgerEntry), то есть lsfLoanDefault/lsfLoanImpaired/lsfLoanOverpayment
  не читались типизированной моделью никак: статус дефолта и impairment займа
  был ненаблюдаем. Добавлено как LoanFlags?
* новые SignerListFlags и DirectoryNodeFlags — сами свойства Flags остаются
  raw uint (смена типа была бы breaking), enum'ы дают именованные константы
  вместо магических чисел; ложный комментарий у LODirectoryNode.Flags про
  «протокол не определяет флагов» исправлен

TestULedgerFlagsConformance — ledger-аналог TestUTxFormatConformance:
вендоренный Fixtures/LedgerFormats.h с пином по sha, парсер, падающий громко
на незнакомом LSF_FLAG* и на тощем разборе, диф в обе стороны и требование
регистрировать каждый флагованный объект — новый объект роняет сборку, а не
пропускается молча. Проверен мутациями: неверное значение, удалённый флаг и
незарегистрированный объект дают внятное падение.

Интеграционное покрытие DynamicMPT (XLS-94): AmendmentGuard + TestIDynamicMPT,
4 теста, каждый читает результат из ledger-объекта. Сценарии выверены по
транзактору rippled, а не по документации.

Версия Xrpl поднята до 10.11.0.0 (minor: только добавления в публичном API),
base-пакеты не менялись. CHANGES.md дополнен.

Проверено: nightly-стенд — TestILoan/TestIDynamicMPT/TestIMPToken 41/41 passed;
юнит-тесты 869/869; сборка решения без ошибок.
@Platonenkov Platonenkov changed the title feat(models): именованные lsf-флаги MPT и интеграционное покрытие DynamicMPT feat(models): флаги ledger-объектов, гвард по LedgerFormats.h и покрытие DynamicMPT (10.11.0.0) Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant