Skip to content

chore: merge develop into testnet/donut (read-state) - #310

Open
0xNilesh wants to merge 81 commits into
testnet/donutfrom
chore/read-state-donut-upgrade
Open

chore: merge develop into testnet/donut (read-state)#310
0xNilesh wants to merge 81 commits into
testnet/donutfrom
chore/read-state-donut-upgrade

Conversation

@0xNilesh

Copy link
Copy Markdown
Member

Brings develop (currently faf01735) onto testnet/donut.

Main contents: the x/ucallback read-state module (PR #300) and the universalClient read-vote changes that go with it.

80 commits, 137 files.

The read-state upgrade handler is not in this PR — it lands separately.

Aman035 and others added 30 commits July 28, 2026 16:59
- decode EvmQueryEnvelope (AccountBalance / ERC20Balance / ContractCall /
  StorageSlot) and SolanaQueryEnvelope (LamportBalance / SPLTokenAccount /
  RawAccountData) from ReadSpec.query
- ExecuteRead on each chain client: deterministic pinned-height queries,
  canonical result encoding for identical-bytes ballot voting
- new RPC methods: GetBalanceAt / GetStorageAt / GetHeaderByNumber (EVM),
  GetBalanceWithSlot / GetAccountInfoWithSlot (SVM)
- pushwatcher listener polls pending reads via gRPC and routes each
  READ_REQUEST event into the target chain's DB (Chains.GetStore)
- EventProcessor gains a READ_REQUEST branch: execute on the chain's own
  reader -> vote -> COMPLETED; corrupt/expired -> REVERTED; transient -> retry
- signer narrowed to consumer-side VoteSigner interface; evm/svm clients
  pass themselves as reader
- implementation plan in docs/read-from-chains-implementation-plan.md
Chain clients own writes to their DB: pushwatcher resolves the target
client via GetClient (same as tss consumers) and hands it the event,
instead of writing into the chain's store directly. Drops the
ExternalChainStoreResolver interface and the chainDBs bookkeeping in
the chains manager.
ChainReader moves next to its consumer (EventProcessor), the uint256
canonical encoder moves to types.go, and the near-no-op bytes32 encoder
is inlined at its single call site.
All query types plus failure modes: eth_call revert, invalid envelopes,
transient RPC failures, slot/height constraints, SPL account validation.
compat/orm-api/module matched the module-dir scan, so it was moved into
api/ and removed, breaking the go.mod replace and failing go mod tidy.
Generated with spawn, ORM scaffolding removed to match the other modules
which all use collections. Genesis moved to keeper/genesis.go.
UniversalRead, ReadRequest and ReadResult. ReadRequest mirrors the fields
universalClient expects; ReadResult carries no error text so ERROR ballots
converge. Aggregates reserved for v2 median support.
Aman035 and others added 29 commits August 7, 2026 16:37
Swap the temporary uread types for the generated ucallback types across
the read listener, parser, and event processor. Key the read event on the
on-chain requestId directly (a unique incrementing nonce) instead of
hashing it. Adds TestConvertReadRequestEvent.
Adopt the generated ucallback ReadRequest/ReadResult across the evm, svm,
and web2 read executors and the shared ReadRequestHandler interface, with a
common NewReadErrorResult helper for votable ERROR observations.
The read path now uses the generated x/ucallback types, so the uread
proto-mirror is no longer referenced.
Classify contract reverts instead of treating every failure as terminal. A revert
rolls the whole tx back, so the deposit stays escrowed — retiring the record there
dropped it from PendingByExpiry and left nothing able to release the funds.

Also switches the expiry retry budget to an explicit counter rather than len(PcTx),
which a failed fulfilment now inflates, and caps it at three.
callbackGasLimit sits between originalFunder and totalPaid, not last. Order is
part of the signature, so this was the wrong topic0 and ingest dropped every
real log. Pinned against the compiled artifact.
Adds the bank and feemarket keepers the settle path needs, grants Burner, and
lifts the module address out of the blocked set so it can hold the escrow it
burns.
protocol_fee, callback_budget, callback_gas_limit and revert_recipient come off
the event. observed_block_height/hash go the other way: the contract does not
take them and nothing consumed them, so they leave the ballot key.
DerivedEVMCall returns (nil, err) when the EVM reverts, discarding res.Ret, so
ClassifyCall could never see a revert reason and CallAlreadySettled was
unreachable. Call DerivedEVMCallWithData instead and drop the wrapper from the
interface so reaching for it is a compile error.
Gate on the budget covering the declared gas limit, then report the cost and
burn exactly that. Report before take: reportCallbackGas releases the refund
and decrements escrow first.
VoteOnBallot fires the terminal hook synchronously at quorum, and that hook
finds the request by ballot key. Assigning afterwards left the deciding vote
looking at the previous observation, so a read that reached quorum sat in
VOTING until the sweeper expired it. The old write also landed after the
hook's, clobbering FULFILLED.
app.EVMKeeper is a *evmkeeper.Keeper assigned further down, so the module was
handed a nil pointer that still satisfies the interface. Every fulfilment would
panic in EndBlock.
Real runtime bytecode with the module-address immutables pre-substituted, plus
a minimal IUniversalCore returning a zero read fee so a request can be created
without the vault.
Ingest of a contract-emitted event, fulfil/settle/burn, the expiry sweep and
EndBlock, vote to quorum through the ballot hook, the admin retry hatch and the
queries. Contract state is read back through the contract's own getters.
Resolves three conflicts:
- app/app.go: keep UcallbackKeeper from develop
- constants.go: keep both 0xC2 = UNIVERSAL_CALLBACK and 0xCA = USigVerifier
- constants_test.go: occupied set is the union of both sides
@0xNilesh 0xNilesh changed the title Merge develop into testnet/donut (read-state) chore: merge develop into testnet/donut (read-state) Aug 19, 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.

2 participants