Skip to content

Feat/ts v4.12.0 - #975

Open
gummy789j wants to merge 8 commits into
release_v4.12.0from
feat/ts-v4.12.0
Open

Feat/ts v4.12.0#975
gummy789j wants to merge 8 commits into
release_v4.12.0from
feat/ts-v4.12.0

Conversation

@gummy789j

Copy link
Copy Markdown
Collaborator

No description provided.

Leon.Zhang and others added 8 commits August 7, 2026 16:07
feat: add TRON governance command domains
Review of d12bd1c (proposal / witness / contract governance, another
contributor's work) against §1 and §2 of the v4.12.0 requirements,
validated live on Nile with a registered witness account.

Two defects made 6 of the 12 new commands unusable against a real node;
both were invisible to the existing tests because those mock the gateway
port, so they could only ever re-assert the adapter's own assumptions.

- getWitness called /wallet/getwitnessbyaddress, which does not exist on
  any node (POST 405 / GET 404 on mainnet and Nile). Every witness-status
  check therefore failed with rpc_error, breaking `witness create`,
  `witness update`, `witness set-brokerage` and — via assertWitness —
  `proposal create`, `proposal approve` and `proposal delete`. Read the
  witness list and filter locally instead: one request, no fan-out, and
  listwitnesses covers every witness rather than only the active 27.

- normalizeProposal rejected an array of parameters and fell back to {},
  but listproposals only ever sends an array. Every proposal reported
  zero parameter changes — the field that says what a proposal does — and
  `proposal create --wait` could not resolve the id of the proposal it
  had just created, since findCreatedProposal matches on that set.

Also gate the writes the Ledger TRON app cannot parse (WitnessCreate,
WitnessUpdate, UpdateBrokerage, ClearABI, UpdateEnergyLimit,
UpdateSetting): governanceTransactionMode already accepted
requireSoftware but no call site passed it, so a Ledger user reached the
device and spent RPCs before APDU 0x6a80. The proposal group stays
ungated — its contract types are on the app's allowlist. See adr/0003.

Tighten `witness create`'s activation check from "empty object" to a
present address, matching accountExists, and make the fixtures realistic.

Adds adapter-level coverage over a verbatim mainnet listproposals payload
and per-command Ledger assertions; both fail if the fixes are reverted.

Verified on Nile: witness update and set-brokerage confirmed on chain
(url change re-read from listwitnesses); proposal create -> id 20662
resolved -> show renders the change -> approve -> already_approved ->
--cancel -> not_approved -> delete -> canceled. Contract governance
reaches real endpoints (not_contract_deployer / contract_not_found).
create2 verified byte-exact against an independent implementation of
Java's formula.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`contract set-origin-energy-limit` was rejected by every node with
"Contract validate error : No contract!" — a message that points at the
contract address, which was in fact correct.

java-tron rebuilds the contract from the `raw_data` json on the
non-visible broadcast path and IGNORES raw_data_hex. A numeric string does
not parse into the int64 field, so the node validated an empty
UpdateEnergyLimitContract, whose contract_address is empty. The CLI
carries int64 quantities as strings by convention, and this builder passed
that string straight into raw_data.

Isolated on Nile with a single signed transaction, mutating only the json
view so the signature and raw_data_hex stayed byte-identical:

  visible:false + hex + "9000000"  -> CONTRACT_VALIDATE_ERROR, No contract!
  visible:false + hex +  9000000   -> accepted

Coerced via #safeNumber, which refuses anything a json number cannot hold
exactly. That replaces the previous "preserve a Java long" behaviour: such
a value could only ever produce a transaction the node rejects, or silently
set a rounded limit. Java's CLI can send int64 max because it speaks
protobuf over gRPC; over HTTP+json we cannot, and refusing is the honest
answer. Real limits are bounded by getTotalEnergyLimit (~1.8e11), far below
the safe-integer ceiling, so nothing reachable is lost.

Verified live on Nile after the fix: origin_energy_limit set to 12000000
and re-read from getcontract. The new test fails if the coercion is
reverted.

Note for follow-up: `proposal create` builds parameter values through the
same local path and also stringifies values above 2^53, so it is likely to
have the same defect. It is not reachable in practice — no TRON chain
parameter is near that magnitude, and the actuator's own range checks
reject absurd values — so it is reported rather than changed blindly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ites

All nine governance writes advertised --build-only and --sign-only and
neither worked: build-only failed outright with "this chain adapter cannot
produce transaction hex", and sign-only silently omitted `hex`, which is
the entire point of the flag. None of the three services passed the
pipeline's `artifact` hook.

Passing it alone would have been wrong. `artifact` serialises through
encodeTransactionHex, and the override table it consulted covered only the
TRC10 types — so ProposalCreate and UpdateEnergyLimit, the two types with
their own exact encoders precisely because tronweb encodes them wrongly,
would have produced hex from tronweb. That is worse than an honest error.

So the override dispatch is unified first: one table in transaction-codec
covering both families, consulted by BOTH protobuf paths. rawDataHexOf had
its own copy of the dispatch, which is how the two could disagree despite
toProtobuf's comment claiming otherwise. tx-integrity then drops its
per-type special-casing and simply compares against rawDataHexOf, removing
the TODO left when the branches were merged.

`artifact` only, deliberately not the full tronTransactionHooks: this group
binds --permission-id in each builder and applies --expiration via
withExtendedExpiration before the pipeline sees the transaction, so also
supplying `prepare` would rebind Permission_id and extend the expiration a
second time. Unifying on prepare is a separate refactor.

Verified end-to-end on Nile, for both custom-encoded types, through the
whole relay the flag exists for — build-only -> tx sign --hex -> tx
broadcast:

  set-origin-energy-limit  146B unsigned -> 213B signed -> confirmed,
                           origin_energy_limit 15000000 read back on chain
  proposal create          122B unsigned -> 189B signed -> confirmed as
                           proposal 20663 with its parameter change intact
                           (deleted afterwards)

sign-only now carries hex (184 bytes on witness set-brokerage).

Both new tests fail if their fix is reverted: the codec test asserts the
two protobuf paths agree and that the encoded value is not the placeholder
zero the exact encoders feed tronweb; the service test asserts all nine
writes pass the hook, including witness create, whose success path cannot
be exercised on chain.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

2 participants