diff --git a/UCALLBACK_IMPLEMENTATION.md b/UCALLBACK_IMPLEMENTATION.md new file mode 100644 index 00000000..2022d86b --- /dev/null +++ b/UCALLBACK_IMPLEMENTATION.md @@ -0,0 +1,569 @@ +# `x/ucallback` — core implementation guide + +**Companion to** `UCALLBACK_MODULE_PLAN.md` (architecture, rationale, open questions). +This file is the build order. Section numbers below match the **actual commits** on +`feat/read-state`, which diverged from the original plan — scaffolding landed before protos, state was +split out of the skeleton, and the protocgen fix was unplanned: + +| # | commit | state | +|---|---|---| +| C0 | `d2e033ce` fix(proto): stop protocgen deleting compat/orm-api | done (unplanned prerequisite) | +| C1 | `b9c966f3` feat(ucallback): scaffold module | done | +| C2 | `d0ad5720` feat(ucallback): add read-state types | done | +| C3 | keeper state + indexes | **staged, in review** | +| C4 | queries | next — unblocks the UV team | +| C5–C9 | ingestion → vote → hook → sweeper → upgrade | planned | + +**Design decisions already locked** (see plan §2 for evidence): + +| decision | why | +|---|---| +| new module `x/ucallback` | clean separation from uexecutor | +| EVM calls made **as the uexecutor module account** | `UniversalCallback.sol:25` hardcodes `0x14191Ea5…` immutable; a `ucallback` module account is rejected by `onlyUEModule` | +| aggregate named `UniversalRead` | read-side sibling of `UniversalTx` | +| `error_msg` absent from the ballot proto entirely | convention-only exclusion will be forgotten once generated | +| ballot key computed over the *identical-mode subset* | v2 `MEDIAN` must be excluded or it's a consensus-breaking change later | +| ingest filters on `log.Address` **and** topic0 | we listen to one trusted contract; the filter is what makes that true | + +--- + +## RESOLVED — expiry semantics + +**Team decision: `expiryPushChainHeight` is the ballot expiry.** The two clocks are fused, not +independent — a read ballot expires exactly when its request does. + +| | clock | set by | enforced at | +|---|---|---|---| +| **A** | `ReadSpec.expiryPushChainHeight` → `ReadRequest.expiry_block_height` | the app, per request | `UniversalCallback.sol:121` on request, `:207` in `expireExternalRead` | +| **B** | `Ballot.block_height_expiry` | **derived from A** | `x/uvalidator/keeper/ballot.go:344` | + +x/uvalidator stores `BlockHeightExpiry = createdHeight + expiryAfterBlocks` +(`x/uvalidator/types/ballot.go:109`), so an absolute deadline has to be handed over as a delta — +`types.BallotExpiryAfterBlocks(expiryHeight, currentHeight)`, floored at 1 so a ballot is never born +expired. We do **not** copy x/uexecutor's inert `DefaultExpiryAfterBlocks = 100_000_000`. + +**What this changed downstream:** + +- An `EXPIRED` ballot now means *the request itself is over*, so the terminal hook retires it — + `expireExternalRead` + status `EXPIRED` — instead of leaving it for the sweeper. A request is + unvotable past its deadline anyway, so waiting would only delay closing it on the contract. +- `REJECTED` still leaves the request in flight; that is not a deadline. +- The C8 sweeper is **still needed**, for requests nobody ever voted on: no vote means no ballot, + which means no terminal hook ever fires. Both paths mark the record terminal, which removes it from + the in-flight set, so whichever runs first the other will not find it. + +Still open from the original three questions: + +1. **Is late fulfilment intended?** `fulfillExternalCallback` has no expiry check — only the + `fulfilledRequests` guard. With the clocks fused this is now narrower in practice (an expired + ballot retires the request promptly), but a quorum reached in the same block as expiry is still a + race between the two paths. +2. **`expireExternalRead` refunds nothing.** Unchanged and unaddressed: the funder's fee stays with + the protocol whichever way a request ends. + +## Reference points in existing code + +Copy these, don't invent: + +``` +x/uexecutor/keeper/evm_hooks.go:21 NewEVMHooks / PostTxProcessing shape +x/uexecutor/keeper/create_outbound.go:27-42 log scan: address filter → topic filter → decode +x/uexecutor/keeper/voting.go:73-125 VoteOnOutboundBallot — the exact voting template +x/uexecutor/keeper/ballot_hooks.go:56 AfterBallotTerminal dispatch +x/uexecutor/keeper/chain_meta.go median-without-ballots (relevant only for v2) +x/uexecutor/types/types.proto:186 UniversalTx shape · :123 PCTx (reuse) +proto/uexecutor/v1/tx.proto:121 MsgVoteOutbound shape +proto/uvalidator/v1/ballot.proto:25 BallotObservationType enum +app/app.go:794 EVMKeeper.SetHooks — currently single-hook +``` + +**The ballot model, stated plainly** — this shapes everything downstream: +`Ballot.votes` is a parallel array of binary `VoteResult{SUCCESS|FAILURE}`. The **ballot ID encodes the +observation**. Distinct observations produce distinct ballots; the one that reaches quorum wins. +Validators do not vote *values*. This is why `VoteChainMeta` bypasses ballots entirely to compute gas +medians, and why v2 `MEDIAN` cannot ride the ballot path. + +--- + +# C2 — protos · DONE `d0ad5720` + +**Files** +``` +proto/ucallback/v1/types.proto +proto/ucallback/v1/genesis.proto +proto/ucallback/v1/params.proto +``` + +```protobuf +// types.proto +message UniversalRead { + option (amino.name) = "ucallback/universal_read"; + option (gogoproto.equal) = true; + + string id = 1; // requestId, 0x-hex uint256 + ReadRequest request = 2; + ReadResult result = 3; // set when the ballot finalises + repeated uexecutor.v1.PCTx pc_tx = 4; // fulfil / expire attempts — REUSE + UniversalReadStatus status = 5; + string ballot_key = 6; +} + +message ReadRequest { + string request_id = 1; + string destination_chain = 2; // CAIP-2, composed by us + bytes owner = 3; + bytes query = 4; + uint32 min_confirmations = 5; + uint64 destination_block_height = 6; + uint64 expiry_block_height = 7; + uint64 created_at_height = 8; // derived from the log's block — NOT in the event + + // core-only, never read by the UV + string callback_target = 9; + string original_funder = 10; + string fees_deposited = 11; + string max_fee = 12; + string requested_tx_hash = 13; + uint64 requested_log_index = 14; +} + +// The ballot payload. NO error_msg field — deliberately. +message ReadResult { + ReadStatus status = 1; + bytes result_data = 2; + uint64 observed_block_height = 3; + bytes observed_block_hash = 4; + // reserved for v2 MEDIAN — excluded from the ballot key when populated + repeated AggregateValue aggregates = 5; +} + +message AggregateValue { + uint32 extract_index = 1; + uint32 mode = 2; + bytes value = 3; +} + +enum ReadStatus { + READ_STATUS_UNSPECIFIED = 0; + READ_STATUS_SUCCESS = 1; + READ_STATUS_ERROR = 2; +} + +enum UniversalReadStatus { + UNIVERSAL_READ_STATUS_UNSPECIFIED = 0; + UNIVERSAL_READ_STATUS_PENDING = 1; + UNIVERSAL_READ_STATUS_VOTING = 2; + UNIVERSAL_READ_STATUS_FULFILLED = 3; + UNIVERSAL_READ_STATUS_EXPIRED = 4; + UNIVERSAL_READ_STATUS_FAILED = 5; // quorum reached, callback reverted +} +``` + +**`ReadRequest` must satisfy `universalClient/uread/types.go:9` field-for-field** — that struct exists +only to be deleted once these types generate. + +**Generate:** `make proto-gen` (Docker required — not the script directly). + +**Verify:** `go build ./...`; generated types exist; `uread.ReadRequest` maps 1:1. + +--- + +# C1 + C3 — module skeleton `b9c966f3`, keeper state (staged) + +**Files** +``` +x/ucallback/module.go AppModule, depinject +x/ucallback/keeper/keeper.go collections wiring +x/ucallback/keeper/genesis.go InitGenesis / ExportGenesis +x/ucallback/types/{keys,codec,errors,constants}.go +app/app.go module registration + maccPerms +``` + +```go +type Keeper struct { + UniversalReads collections.Map[string, types.UniversalRead] + PendingByExpiry collections.KeySet[collections.Pair[uint64, string]] // in-flight set + ReadsByTxHash collections.KeySet[collections.Pair[string, string]] // (txHash, requestId) + Params collections.Item[types.Params] + + evmKeeper types.EVMKeeper + uexecutorKeeper types.UexecutorKeeper // for module addr + DerivedEVMCall + uvalidatorKeeper types.UvalidatorKeeper // for eligible voters + VoteOnBallot +} +``` + +`ReadsByTxHash` exists because a single Push transaction can emit several `ReadRequested` logs — +a batching app, or a contract that fires more than one `_requestRead` in one call. Each becomes its +own `UniversalRead` keyed by `requestId` (they share no lifecycle: one can be FULFILLED while its +sibling EXPIRES), so this index is what reassembles the batch for `reads-by-tx`. Ordered composite +key, prefix-scanned by `txHash`. + +`PendingByExpiry` **must** be an ordered composite key so the sweeper can range-scan +`[0, currentHeight]` rather than iterating the whole set. + +> Adding `ucallback` to `maccPerms` puts its address into `BlockedAddresses()`, and since cosmos/evm +> v0.7 that list also gates `SetBalance` — so the module address can't receive native EVM value. +> That is almost certainly correct here; note it if not. + +**Verify:** chain starts, genesis round-trips, `q ucallback params` responds. + +--- + +# C4 — queries ← **ship this early, it unblocks the UV team** + +**Files** +``` +proto/ucallback/v1/query.proto +x/ucallback/keeper/grpc_query.go +x/ucallback/client/cli/query.go +``` + +```protobuf +rpc AllPendingReadRequests(QueryAllPendingReadRequestsRequest) + returns (QueryAllPendingReadRequestsResponse); // paginated +rpc GetUniversalRead(QueryGetUniversalReadRequest) + returns (QueryGetUniversalReadResponse); +rpc ReadsByTxHash(QueryReadsByTxHashRequest) + returns (QueryReadsByTxHashResponse); // all reads from one Push tx +``` + +`AllPendingReadRequests` returns `[]ReadRequest` where status is `PENDING`. Mirror +`AllPendingOutbounds` for pagination shape. + +**Why third and not last:** it deletes `ErrReadQueriesNotAvailable` in +`universalClient/pushcore/pushCore.go:382` and lets the UV team integrate against a real endpoint — +even while it returns an empty list. Their TODO names this exact query. + +`ReadsByTxHash` prefix-scans `ReadsByTxHash` and returns the full `UniversalRead` for each hit — +`q ucallback reads-by-tx `. This is how a batched request is inspected as a unit, and it is why +we can key records by `requestId` without losing the grouping. + +`GetUniversalRead` is the operator tool. Model the CLI on `q uexecutor v2 get-universal-tx`; that query +is what made a stranded production tx diagnosable in minutes this week. + +**Verify:** UV team's `GetAllPendingReadRequests` returns `[]` instead of an error. + +--- + +# C5 — ingestion + +**Files** +``` +x/ucallback/keeper/evm_hooks.go +x/ucallback/keeper/ingest.go +x/ucallback/types/event_decode.go +app/app.go ← rewire to MultiEvmHooks +``` + +```go +func (h EVMHooks) PostTxProcessing(ctx sdk.Context, sender common.Address, + msg core.Message, receipt *ethtypes.Receipt) error { + if err := h.k.IngestReadRequests(ctx, receipt); err != nil { + h.k.Logger().Error("ucallback ingest failed", "tx", receipt.TxHash, "err", err) + } + return nil // NEVER non-nil — see below +} +``` + +> 🔴 `MultiEvmHooks.PostTxProcessing` aborts the whole hook chain on the first error +> (`x/vm/keeper/hooks.go:40-42`), which **fails the EVM transaction**. A bug in our hook would break +> unrelated user txs. Log and continue; never return an error for anything short of a consensus fault. + +```go +// ingest.go — mirrors create_outbound.go:27-42 +for _, lg := range receipt.Logs { + if lg.Removed { continue } + if !strings.EqualFold(lg.Address, ucAddr) { continue } + if len(lg.Topics) == 0 { continue } + if !strings.EqualFold(lg.Topics[0], ReadRequestedSig) { continue } + + ev, err := types.DecodeReadRequestedFromLog(lg) + if err != nil { k.Logger().Error(...); continue } + + if has, _ := k.UniversalReads.Has(ctx, ev.RequestID); has { continue } // idempotent + + ur := types.UniversalRead{ + Id: ev.RequestID, + Request: &types.ReadRequest{ + RequestId: ev.RequestID, + DestinationChain: ev.ChainNamespace + ":" + ev.ChainId, + Owner: ev.Owner, + Query: ev.Query, + MinConfirmations: uint32(ev.MinConfirmations), + DestinationBlockHeight: ev.BlockNumber, + ExpiryBlockHeight: ev.ExpiryPushChainHeight, + CreatedAtHeight: uint64(ctx.BlockHeight()), + CallbackTarget: ev.CallbackTarget, + OriginalFunder: ev.OriginalFunder, + FeesDeposited: ev.FeesDeposited.String(), + MaxFee: ev.MaxFee.String(), + RequestedTxHash: receipt.TxHash.Hex(), + RequestedLogIndex: uint64(lg.Index), + }, + Status: types.UNIVERSAL_READ_STATUS_PENDING, + } + k.UniversalReads.Set(ctx, ev.RequestID, ur) + k.PendingByExpiry.Set(ctx, collections.Join(ev.ExpiryPushChainHeight, ev.RequestID)) +} +``` + +**app.go — `SetHooks` panics if called twice** (`x/vm/keeper/keeper.go:255`), and line 794 already +registers uexecutor's: + +```go +app.EVMKeeper.SetHooks(evmkeeper.NewMultiEvmHooks( + uexecutorkeeper.NewEVMHooks(app.UexecutorKeeper), + ucallbackkeeper.NewEVMHooks(app.UcallbackKeeper), +)) +``` + +**⚠️ Put `ReadRequestedSig` and the `UniversalCallback` address in chain config, not Go constants.** +uexecutor hardcodes both, and that has already failed in production: `constants.go:56` still declares +`RescueFundsOnSourceChain(...)` for an event the contract renamed to `FundsRescued`, so it silently +matches nothing. Register these like `gateway_methods` / `vault_methods`. + +**Tests** +- a log from a **non-UniversalCallback** address is ignored (regression test — this is the filter that makes "we only listen to one trusted contract" true) +- wrong topic0 ignored +- duplicate log → single record +- `created_at_height` equals the block height, not anything from the event + +--- + +# C6 — vote message and ballot + +**Files** +``` +proto/uvalidator/v1/ballot.proto + BALLOT_OBSERVATION_TYPE_READ_RESULT = 5 +proto/ucallback/v1/tx.proto MsgVoteReadResult +x/ucallback/keeper/msg_vote_read_result.go +x/ucallback/keeper/voting.go VoteOnReadBallot +x/ucallback/types/keys.go GetReadBallotKey +``` + +```protobuf +rpc VoteReadResult(MsgVoteReadResult) returns (MsgVoteReadResultResponse); + +message MsgVoteReadResult { + option (amino.name) = "ucallback/MsgVoteReadResult"; + option (cosmos.msg.v1.signer) = "signer"; + string signer = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string request_id = 2; + ReadResult result = 3; +} +``` + +```go +// keys.go — mode-aware from day one. +// v1: every field is IDENTICAL, so this equals H(all of result_data). +// v2: aggregates are EXCLUDED here and medianed separately at quorum. +func GetReadBallotKey(requestId string, r *ReadResult) (string, error) { + // hash: requestId ‖ status ‖ result_data ‖ observed_block_height ‖ observed_block_hash + // NOT hashed: aggregates, and error_msg does not exist in the proto +} +``` + +```go +// voting.go — copy x/uexecutor/keeper/voting.go:73-125 verbatim, swapping the observation type +func (k Keeper) VoteOnReadBallot(ctx, universalValidator sdk.ValAddress, + requestId string, res *types.ReadResult) (isFinalized, isNew bool, err error) { + ballotKey, err := types.GetReadBallotKey(requestId, res) + voters, _ := k.uvalidatorKeeper.GetEligibleVoters(ctx) + votesNeeded := (types.VotesThresholdNumerator*len(voters))/types.VotesThresholdDenominator + 1 + + _, isFinalized, isNew, err = k.uvalidatorKeeper.VoteOnBallot( + ctx, ballotKey, + uvalidatortypes.BallotObservationType_BALLOT_OBSERVATION_TYPE_READ_RESULT, + universalValidator.String(), + uvalidatortypes.VoteResult_VOTE_RESULT_SUCCESS, + voterAddrStrs, int64(votesNeeded), + types.BallotExpiryAfterBlocks(req.ExpiryBlockHeight, ctx.BlockHeight()), + ) + // ballotKey is stored on the UniversalRead itself; there is no reverse index. + // AfterBallotTerminal resolves it by scanning PendingByExpiry — see + // GetUniversalReadByBallot. + return +} +``` + +**Msg server guards:** request exists · status is `PENDING` or `VOTING` · signer is an eligible +universal validator · not already `FULFILLED`/`EXPIRED`. + +**Open decision (plan Q2):** whether to reject `READ_STATUS_ERROR` ballots that carry no revert +evidence. PR #296's EVM executor votes ERROR on *any* `CallContract` failure — including pruned nodes +and 429s — and because ERROR ballots are byte-identical by design, infra faults converge into a +confident quorum. Decide before this commit lands. + +**Tests** +- two validators, identical results → one ballot, converges +- two validators, different `result_data` → two ballots, neither converges +- non-validator signer rejected +- vote on a `FULFILLED` request rejected + +--- + +# C7 — ballot terminal hook and fulfilment + +**Files** +``` +x/ucallback/keeper/ballot_hooks.go +x/ucallback/keeper/fulfill.go +x/ucallback/types/abi.go UniversalCallback ABI +``` + +```go +func (h BallotHooks) AfterBallotTerminal(ctx, ballotKey string, + ballotType uvalidatortypes.BallotObservationType, ...) error { + switch ballotType { + case uvalidatortypes.BallotObservationType_BALLOT_OBSERVATION_TYPE_READ_RESULT: + return h.afterReadBallotTerminal(ctx, ballotKey) + } + return nil +} +``` + +```go +// fulfill.go +func (k Keeper) FulfillRead(ctx sdk.Context, ur types.UniversalRead) error { + abi, _ := types.ParseUniversalCallbackABI() + ueModuleAcc, _ := k.uexecutorKeeper.GetUeModuleAddress(ctx) + isModuleSender, nonce, _ := k.uexecutorKeeper.ModuleSenderNonce(ctx, ueModuleAcc) + + resp, err := k.evmKeeper.DerivedEVMCall( + ctx, abi, + ueModuleAcc, // MUST be uexecutor — contract hardcodes 0x14191Ea5… + universalCallbackAddr, + big.NewInt(0), nil, // gasLimit nil — estimate, per house convention + true, /*commit*/ false, /*gasless*/ + isModuleSender, nonce, + "fulfillExternalCallback", + requestIdBig, ur.Result.ResultData, + ur.Result.ObservedBlockHeight, ur.Result.ObservedBlockHash, + ) + + ur.PcTx = append(ur.PcTx, &uexecutortypes.PCTx{ + BlockHeight: uint64(ctx.BlockHeight()), + Status: err == nil && resp != nil && resp.VmError == "", + ErrorMsg: errMsgOf(err, resp), // ← the field that saves you at 2am + }) + if success { ur.Status = FULFILLED } else { ur.Status = FAILED } + k.PendingByExpiry.Remove(ctx, collections.Join(ur.Request.ExpiryBlockHeight, ur.Id)) + k.UniversalReads.Set(ctx, ur.Id, ur) +} +``` + +> **Decision: `gasLimit` is `nil`.** Ten of the eleven existing `DerivedEVMCall` sites pass `nil` +> and let `EstimateGasInternal` size it; only `CallUEAExecutePayload` passes a value, and only +> because the user's signed payload supplies one. We follow the convention. +> +> Consequence: we never need `callbackGasLimit`, so there is no `getPendingRead` call in the fulfil +> path and no dependency on contracts emitting it in `ReadRequested`. +> +> Residual risk, recorded not mitigated: the estimator's own doc says it *"may underpredict"*, and a +> `nil` site is how `CallPRC20Deposit` produced `intrinsic gas too low` on donut this week. If a read +> ever underpredicts, that request fails terminally (F4). The fix would be passing an explicit limit +> here — localised to this one call. + +> 🔴 **Never set `FULFILLED` optimistically.** If the submit itself fails (nonce drift, gas), the +> ballot is terminal but the callback never landed — you must be able to retry until expiry. + +**Note the uexecutor module-nonce drift bug**: module-sender calls skip `ModuleAccountNonce` +increment. Fix it before adding a fourth caller, or `FulfillRead` inherits it. + +**Tests** +- quorum → `fulfillExternalCallback` called with exactly the voted values +- callback reverts → `FAILED` + `error_msg` recorded, no retry +- submit fails → status unchanged, still retryable +- gas: `gasleft()` at the call ≥ `callbackGasLimit` + +--- + +# C8 — expiry sweeper + +**Files** +``` +x/ucallback/keeper/expire.go +x/ucallback/module.go EndBlock +app/app.go SetOrderEndBlockers +``` + +```go +func (k Keeper) SweepExpired(ctx sdk.Context) error { + h := uint64(ctx.BlockHeight()) + rng := collections.NewPrefixUntilPairRange[uint64, string](h) + n := 0 + for iter, _ := k.PendingByExpiry.Iterate(ctx, rng); iter.Valid() && n < maxExpiriesPerBlock; iter.Next() { + // DerivedEVMCall → expireExternalRead(requestId), same sender rules as C7 + // record PCTx, status = EXPIRED, de-index + n++ + } +} +``` + +Bound it per block — unbounded makes a fat EndBlocker, too low and a backlog never drains. + +> **Narrower than originally planned.** With ballot expiry fused to the request deadline (see +> RESOLVED at the top), the terminal hook already retires any request that attracted at least one +> vote. The sweeper's remaining job is requests that were *never voted on* — no vote means no ballot, +> so no hook ever fires for them. Cadence is therefore not urgent: nothing user-visible depends on +> prompt expiry, and `expireExternalRead` refunds nothing either way. + +> The contract's `expireExternalRead` **transfers nothing** (verified: zero value-transfer statements), +> so the funder's fee is trapped. That is a contracts bug, not ours — but our sweeper is what makes it +> visible, so record it clearly in the `PCTx` and surface it in `GetUniversalRead`. + +**Tests** +- request past expiry swept exactly once +- request at exactly `expiryHeight` — decide inclusive/exclusive and pin it +- fulfil/expire race: contract's `fulfilledRequests` guard means first-wins; core must swallow the + loser's revert without corrupting status + +--- + +# C9 — upgrade handler + +**Files** +``` +app/upgrades//upgrade.go +app/upgrades.go +``` + +New store key → `StoreUpgrades.Added: []string{"ucallback"}`. + +**Not a no-op `RunMigrations` — the handler must also deploy UniversalCallback at 0xC2.** +Verified against donut (chain 42101, height 20,791,174): `0x…C2`, `0xF2…C2` and `0xF1…C2` are all +empty — `code: 0x`, balance 0, nonce 0. Only the explicitly-named `SYSTEM_CONTRACTS` entries +(`0xAA 0xB0 0xB1 0xB2 0xBC 0xC0 0xC1`) are live; every `RESERVED_*` slot (`0xA0 0xA5 0xB3 0xC2 0xCF`) +is empty, because the deploy loop in `x/uregistry/keeper/genesis.go` runs at `InitGenesis` only and +donut's genesis predates the `init()` that added those reservations. + +So promoting `RESERVED_C2` → `UNIVERSAL_CALLBACK` is free on donut (nothing there either way), but the +real contract will not appear on its own — the handler has to deploy the admin + impl + proxy triple +explicitly, the way genesis would have. + +> Related, and worth raising with the team separately: the F-2026-17025 squatting defence is **not in +> effect on donut**. The A/B/C reserved slots are empty and claimable there. Pre-existing, but we are +> about to place a contract in that range. + +**Verify with a real upgrade simulation** from the current donut release to this branch — the +established flow: start the old binary, submit `MsgSoftwareUpgrade` at a height well past the end of +the voting period, let cosmovisor swap, confirm `q upgrade applied`, then run a tx. + +> Set the proposal height generously past the **end of the voting period**, not just the submit +> height — two simulation proposals failed with `upgrade cannot be scheduled in the past` learning +> this. + +--- + +## Ordering rationale + +C1→C3 are prerequisites. **C4 (queries) is deliberately early**: it is cheap, it unblocks the UV team, +and it can ship returning an empty list. C5 (ingestion) makes records real. C6–C7 are the consensus +core and should land together in review even if committed separately. C8 (sweeper) is safe to add last +because until it exists, expired requests simply accumulate — no corruption. C9 gates deployment. + +## Cross-team dependencies + +Nothing here is blocked on contracts. But six contract defects change behaviour at the edges, and all +are cheap while `feat-read-state` is unmerged — F6 (**no status channel in +`fulfillExternalCallback`**) is the only one with no core-side workaround. Full list in the plan §10. diff --git a/UCALLBACK_MODULE_PLAN.md b/UCALLBACK_MODULE_PLAN.md new file mode 100644 index 00000000..bccad453 --- /dev/null +++ b/UCALLBACK_MODULE_PLAN.md @@ -0,0 +1,441 @@ +# `x/ucallback` — Read-from-Chains, core-side module plan + +**Status:** Draft for review · **Written:** 2026-08-04 +**Scope:** core chain only. Contracts (`push-chain-core-contracts@feat-read-state`) and universal +validators (`push-chain-node#296`) are owned by other teams; both are already written, which means +**our interface is pinned from both ends**. + +Every claim below is cited to a file:line or a live query. Open questions are collected in §9. + +--- + +## 1. What we own + +``` +┌─ contracts (done, branch) ┌─ UV (done, draft PR #296) +│ UniversalCallback.sol │ externalchains/{evm,svm,web2}/read_executor.go +│ emits ReadRequested │ pushwatcher/ → polls us +│ exposes fulfillExternalCallback │ pushcore.GetAllPendingReadRequests() ← STUB +│ expireExternalRead │ +└────────────┬───────────────────────────────┴──────────┬───────────────── + │ │ + ┌────▼──────────────────────────────────────────▼────┐ + │ x/ucallback ← US │ + │ ingest ReadRequested → serve pending → tally │ + │ ballot → call fulfill/expire → record outcome │ + └─────────────────────────────────────────────────────┘ +``` + +The UV's stub states our deliverable verbatim (`universalClient/pushcore/pushCore.go:377`): + +> `TODO(core): blocked on x/uexecutor Query/PendingReadRequests … mirror GetAllPendingOutbounds` + +Note it says `x/uexecutor`. We are choosing `x/ucallback` instead — see §2.1 for why that is fine +and §9 Q1 for the one thing it forces. + +--- + +## 2. Hard constraints discovered + +### 2.1 🔴 The EVM caller must be the **uexecutor** module account + +`UniversalCallback.sol:25` hardcodes an immutable: + +```solidity +address public immutable UNIVERSAL_EXECUTOR_MODULE = 0x14191Ea54B4c176fCf86f51b0FAc7CB1E71Df7d7; +modifier onlyUEModule() { if (msg.sender != UNIVERSAL_EXECUTOR_MODULE) revert CallerIsNotUEModule(); } +``` + +Verified against live donut: + +``` +uexecutor module push1zsv3af2tfstklnux75dsltruk8n3ma7hnxp8ew + → hex 0x14191ea54b4c176fcf86f51b0fac7cb1e71df7d7 ← identical +``` + +A new module gets `authtypes.NewModuleAddress("ucallback")`, a **different** address. Every +`fulfillExternalCallback` would revert. + +**Decision taken:** `x/ucallback` owns state and lifecycle; the EVM call is executed *as uexecutor* +by calling into the uexecutor keeper. No contract change, no redeploy coupling. + +> Consequence: we inherit uexecutor's module-nonce path, including the known drift bug where +> module-sender calls skip `ModuleAccountNonce` increment. Fix that before adding a fourth caller. + +### 2.2 🔴 `SetHooks` panics if called twice + +`x/vm/keeper/keeper.go:254`: + +```go +func (k *Keeper) SetHooks(eh types.EvmHooks) *Keeper { + if k.hooks != nil { panic("cannot set evm hooks twice") } +``` + +and `app/app.go:794` already does `app.EVMKeeper.SetHooks(uexecutorkeeper.NewEVMHooks(...))`. + +**Solution:** `evmkeeper.NewMultiEvmHooks(uexecutorHooks, ucallbackHooks)` (`x/vm/keeper/hooks.go:27`). + +> ⚠️ `MultiEvmHooks.PostTxProcessing` aborts the whole chain of hooks on the first error +> (`hooks.go:40-42`). A bug in our hook therefore **fails unrelated EVM transactions**. Our hook +> must never return a non-nil error for anything short of a genuine consensus fault — log and +> continue instead. + +### 2.3 🟡 Known defects on the contract side we must design around + +| defect | effect on us | +|---|---| +| `expireExternalRead` transfers nothing (verified: 0 value-transfer statements) | our sweeper "expires" a request but the funder is never repaid; fees accrue in the contract | +| refund uses `call{value}` + `revert` on failure | an app without `receive()` makes `fulfillExternalCallback` revert **forever**; our submit will never succeed | +| `fulfilledRequests[requestId] = true` set *before* dispatch | whatever we submit is final; a quorum on ERROR is permanent, no retry | +| `_localContext` leaks in the app on the failure/expiry paths | not ours, but it's what users will report to us | + +These are raised with the contracts team (§10). Our design must not *depend* on them being fixed. + +--- + +## 3. Data model + +### 3.1 `UniversalRead` — the aggregate + +Named as the read-side sibling of `UniversalTx` (`proto/uexecutor/v1/types.proto:186`). Deliberately +**not** a clone: a read is triggered by a Push-chain event, performs no external write, has no +external tx hash, and produces exactly one Push-chain fulfilment. + +```protobuf +// proto/ucallback/v1/types.proto +message UniversalRead { + option (amino.name) = "ucallback/universal_read"; + + string id = 1; // requestId, 0x-hex uint256 + ReadRequest request = 2; + ReadResult result = 3; // set when the ballot finalises + repeated PCTx pc_tx = 4; // fulfil / expire attempts (reuse uexecutor's PCTx) + UniversalReadStatus status = 5; + string ballot_key = 6; +} +``` + +`pc_tx` is repeated (fulfil, then possibly expire); `request`/`result` are singular. There is no +top-level `revert_error` — failures live in `PCTx.error_msg`, which is the field that made a stuck +`UniversalTx` debuggable in production. + +### 3.2 `ReadRequest` — served verbatim to UVs + +```protobuf +message ReadRequest { + string request_id = 1; + string destination_chain = 2; // CAIP-2, composed by us + bytes owner = 3; + bytes query = 4; + uint32 min_confirmations = 5; // uint16 on the wire + uint64 destination_block_height = 6; + uint64 expiry_block_height = 7; + uint64 created_at_height = 8; // derived — NOT in the event + + // core-only, never consumed by the UV + string callback_target = 9; + string original_funder = 10; + string fees_deposited = 11; // uint256 as string + string max_fee = 12; + string requested_tx_hash = 13; // provenance / dedup / debugging + uint64 requested_log_index = 14; +} +``` + +Field-for-field this must satisfy `uread.ReadRequest` (`universalClient/uread/types.go:9`), the +temporary struct we are meant to delete. + +### 3.3 `ReadResult` — the ballot payload + +```protobuf +message ReadResult { + ReadStatus status = 1; + bytes result_data = 2; + uint64 observed_block_height = 3; + bytes observed_block_hash = 4; +} +``` + +**`error_msg` is deliberately absent from the proto**, not merely unused. In `uread` it is excluded +by a comment — *"local diagnostic only — never part of the ballot"*. Once it is a generated type +that convention will be forgotten; make it structurally impossible. If error text ever enters the +ballot key, no two validators ever agree. + +### 3.4 Enums + +```protobuf +enum ReadStatus { READ_STATUS_UNSPECIFIED = 0; READ_STATUS_SUCCESS = 1; READ_STATUS_ERROR = 2; } + +enum UniversalReadStatus { + UNIVERSAL_READ_STATUS_UNSPECIFIED = 0; + UNIVERSAL_READ_STATUS_PENDING = 1; // ingested, awaiting votes + UNIVERSAL_READ_STATUS_VOTING = 2; // ≥1 vote, no quorum + UNIVERSAL_READ_STATUS_FULFILLED = 3; // callback dispatched OK + UNIVERSAL_READ_STATUS_EXPIRED = 4; // expireExternalRead submitted + UNIVERSAL_READ_STATUS_FAILED = 5; // quorum reached, callback reverted +} +``` + +### 3.5 Contract → our fields + +| our field | from `ReadRequested` | +|---|---| +| `request_id` | `requestId` | +| `destination_chain` | `account.chainNamespace + ":" + account.chainId` | +| `owner` / `query` / `min_confirmations` | `account.owner` / `readSpec.query` / `readSpec.minConfirmations` | +| `destination_block_height` | `readSpec.blockNumber` | +| `expiry_block_height` | `readSpec.expiryPushChainHeight` | +| `callback_target` / `original_funder` / `fees_deposited` / `max_fee` | same-named event args | +| **`created_at_height`** | **not emitted** — take from the log's Push block height | + +--- + +## 4. Storage + +``` +UniversalReads : requestId → UniversalRead (collections.Map) +PendingByExpiry : (expiryHeight, requestId) → () (KeySet, in-flight set) +ReadsByTxHash : (pushTxHash, requestId) → () (KeySet, batch reassembly) +Params : module params +``` + +There is deliberately **no `ballotKey → requestId` index**. The ballot terminal hook resolves a ballot +by scanning `PendingByExpiry`, which holds only unsettled reads — the same trade uexecutor already +makes in `ballot_hooks.go:86` for the identical problem. That leaves `PendingByExpiry` with two +consumers, so it stays regardless of how the open expiry-cadence question is answered. + +`PendingByExpiry` must be an ordered composite key so the sweeper can range-scan +`[0, currentHeight]` in `EndBlocker` rather than iterating everything. + +--- + +## 5. Components + +``` +proto/ucallback/v1/{types,tx,query,genesis,params}.proto +x/ucallback/ + keeper/ + keeper.go collections wiring, uexecutor + uvalidator keeper refs + evm_hooks.go PostTxProcessing → ingest ReadRequested + ingest.go log filter + decode → UniversalRead{PENDING} + msg_vote_read_result.go MsgVoteReadResult → VoteOnReadBallot + ballot_hooks.go AfterBallotTerminal(READ_RESULT) → fulfil + fulfill.go call UniversalCallback.fulfillExternalCallback via uexecutor + expire.go EndBlocker sweeper → expireExternalRead + grpc_query.go AllPendingReadRequests, GetUniversalRead + types/ + constants.go keys.go codec.go errors.go events.go + module.go / depinject +``` + +### 5.1 Ingestion (`evm_hooks.go` + `ingest.go`) + +Mirrors `x/uexecutor/keeper/create_outbound.go:27-42`: + +```go +for _, lg := range receipt.Logs { + if lg.Removed { continue } + if !strings.EqualFold(lg.Address, universalCallbackAddr) { continue } // ← MANDATORY + if len(lg.Topics) == 0 || !strings.EqualFold(lg.Topics[0], ReadRequestedEventSig) { continue } + ... +} +``` + +**The address filter is a security control, not a nicety.** Matching on topic0 alone lets anyone +deploy a contract emitting an identical `ReadRequested` and conscript the entire validator set into +performing free external reads — a cheap DoS. The eventual `fulfillExternalCallback` would be +rejected (`InvalidRequestId`), so no funds move, but validator work and module txs are burned. + +### 5.2 Query (`grpc_query.go`) + +```protobuf +rpc AllPendingReadRequests(QueryAllPendingReadRequestsRequest) + returns (QueryAllPendingReadRequestsResponse); // paginated, mirrors AllPendingOutbounds +rpc GetUniversalRead(QueryGetUniversalReadRequest) + returns (QueryGetUniversalReadResponse); // mirrors v2 GetUniversalTx +``` + +`AllPendingReadRequests` is the one the UV is blocked on. `GetUniversalRead` is the operator tool — +the `get-universal-tx` equivalent that made a stuck production tx diagnosable in minutes. + +### 5.3 Voting + +```protobuf +rpc VoteReadResult(MsgVoteReadResult) returns (MsgVoteReadResultResponse); + +message MsgVoteReadResult { + option (cosmos.msg.v1.signer) = "signer"; + string signer = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string request_id = 2; + ReadResult result = 3; +} +``` + +Mirrors `MsgVoteOutbound` (`proto/uexecutor/v1/tx.proto:121`). Requires a new enum value in +`proto/uvalidator/v1/ballot.proto:25`: + +```protobuf +BALLOT_OBSERVATION_TYPE_READ_RESULT = 5; +``` + +`ballotKey = H(requestId ‖ status ‖ resultData ‖ observedBlockHeight ‖ observedBlockHash)` — +**excluding** error text. + +### 5.4 Ballot terminal hook + +Extend `BallotHooks.AfterBallotTerminal` (`x/uexecutor/keeper/ballot_hooks.go:56`) with a +`BALLOT_OBSERVATION_TYPE_READ_RESULT` case → `afterReadBallotTerminal` → §5.5. + +### 5.5 Fulfilment + +Call `UniversalCallback.fulfillExternalCallback(requestId, resultData, observedBlockHeight, +observedBlockHash)` through uexecutor's `DerivedEVMCall` so `msg.sender` is the uexecutor module +(§2.1). Record the outcome as a `PCTx` — **including `error_msg` on failure** — and set status +`FULFILLED` or `FAILED`. + +> `fulfillExternalCallback` does `call{gas: callbackGasLimit}` with `callbackGasLimit` up to +> `MAX_CALLBACK_GAS_LIMIT = 1_000_000` and performs **no 63/64 check**. Since we are the caller, we +> must ensure `gasleft() ≥ callbackGasLimit × 64/63 + buffer` before dispatch, or the callback +> silently under-runs and fails permanently. + +### 5.6 Expiry sweeper + +`EndBlocker`: range-scan `PendingByExpiry` over `[0, ctx.BlockHeight()]`, submit +`expireExternalRead(requestId)`, mark `EXPIRED`. Bound the per-block count (§9 Q5). + +--- + +## 6. Wiring (`app/app.go`) + +```go +app.EVMKeeper.SetHooks(evmkeeper.NewMultiEvmHooks( + uexecutorkeeper.NewEVMHooks(app.UexecutorKeeper), + ucallbackkeeper.NewEVMHooks(app.UcallbackKeeper), +)) +``` + +Replaces the single-hook call at `app/app.go:794`. Plus: module registration, `SetOrderEndBlockers` +entry for the sweeper, and a `ucallback` entry in `maccPerms`. + +> `BlockedAddresses()` derives from `GetMaccPerms()`, and since cosmos/evm v0.7 the blocked list also +> gates `SetBalance`. Adding `ucallback` to `maccPerms` therefore makes its address unable to receive +> native EVM value. That is almost certainly what we want — flag it if not. + +--- + +## 7. Delivery order + +1. protos + generated types (`make proto-gen`, Docker) +2. storage + keeper skeleton + genesis +3. `AllPendingReadRequests` → **unblocks the UV team immediately**, even returning empty +4. ingestion hook + `MultiEvmHooks` rewire +5. `MsgVoteReadResult` + ballot type + tally +6. terminal hook → fulfilment +7. expiry sweeper +8. `GetUniversalRead` + CLI +9. upgrade handler (new store key → `StoreUpgrades.Added`) + +Step 3 is deliberately early and cheap: it deletes `ErrReadQueriesNotAvailable` and lets the UV team +integrate against a real endpoint while the rest lands. + +--- + +## 8. Testing + +- ingestion: forged log from a non-`UniversalCallback` address is **ignored** (security regression test) +- ballot: two validators voting identical results converge; differing `error_msg` must not split them +- fulfilment: callback revert → `FAILED` + `error_msg` recorded, request not retried +- expiry: request past `expiry_block_height` is swept exactly once +- upgrade sim from the current donut release with the new store key + +--- + +## 9. Open questions / decisions needed + +**Q1 — module name vs the UV's expectation.** +The UV stub targets `x/uexecutor Query/PendingReadRequests`. If we ship `x/ucallback`, the UV team +must change the client path and proto import. Cheap, but it is a cross-team change that must be +agreed *before* they unblock. **Do we confirm `ucallback` with them now?** + +**Q2 — should we ever submit an ERROR ballot?** +PR #296's EVM executor votes ERROR on *any* `CallContract` failure +(`externalchains/evm/read_executor.go:61`), including non-archive nodes, 429s and timeouts — while +the SVM and web2 executors correctly treat transport failures as transient. Because ERROR ballots are +byte-identical by design, validators failing for unrelated infrastructure reasons converge into a +confident quorum indistinguishable from a genuine revert — and the contract makes it permanent. +**Do we harden core-side (refuse ERROR ballots lacking revert evidence), or require the UV fix first?** + +**Q3 — retry semantics.** +The contract marks `fulfilledRequests[requestId] = true` before dispatch, so a reverted callback is +terminal. Do we (a) accept that and record `FAILED`, or (b) ask contracts to mark fulfilled only on +success so a retry is possible? (b) is a contract change and must be requested while they are still +on a branch. + +**Q4 — do we gate on Push-chain confirmations before serving a request?** +The UV sets `ConfirmationType: store.ConfirmationInstant` (`pushwatcher/event_parser.go:114`) — it +acts immediately on whatever we serve. If we serve from a block that later reorgs, validators do work +for a request that never existed. **Serve immediately, or hold N blocks?** + +**Q5 — sweeper budget.** +Max expiries per block? Unbounded risks a fat EndBlocker; too low and a backlog never drains. + +**Q6 — who pays for callback gas?** +There is **no validator/reader reward path anywhere in `UniversalCallback.sol`** (grep: 0 matches). +The `callbackGasLimit × tx.gasprice` component is collected then refunded in full on both success and +failure — it pays nobody. The module bears real execution cost for up to 1M gas per read, gasless. +**Is that intentional for v1?** + +**Q7 — `ReadRequested` topic + `UniversalCallback` address: config or Go constants?** +uexecutor hardcodes both (`types/constants.go`, `uregistrytypes.SYSTEM_CONTRACTS`). That pattern has +already failed once in production: `RescueFundsOnSourceChainEventSig` still declares a signature the +contract renamed to `FundsRescued`, and it silently matches nothing. **Strong recommendation: put both +in chain config**, like `gateway_methods` / `vault_methods`. + +**Q9 — 🔴 web2 reads cannot be expressed by the contract.** +The UV has a complete web2 path (`externalchains/web2/read_executor.go`, 418 lines, SSRF-hardened), +`uread` documents the CAIP form `web2:https` and marks `DestinationBlockHeight` *"not applicable for +web2"*. But the contracts contain **zero** web2 references, and `requestExternalReadSelf` rejects it: + +```solidity +if (spec.blockNumber == 0 + || spec.blockNumber > _universalCore.chainHeightByChainNamespace(...)) revert InvalidBlockNumber(); +if (spec.account.owner.length == 0) revert InvalidAccountId(); +if (spec.minConfirmations < MIN_CONFIRMATIONS_FLOOR) revert InvalidMinConfirmations(); +``` + +A web2 request would need a fabricated `blockNumber`, a fictional `web2` namespace height in +`UniversalCore` exceeding it, a dummy `owner` (the URL lives in `query`), and a meaningless +`minConfirmations ≥ 1`. + +Ballots still converge — every web2 voter reports height `0` and an empty hash — so the tally needs no +special case. The costs are (a) we persist and serve a fake `destination_block_height`, and (b) any +future confirmation-gating on our side must exempt web2. + +**Is web2 in scope for v1? If yes, the contract needs a namespace-aware validation branch. If no, the +UV's web2 executor is dead code and we should not model for it.** + +**Q8 — one `ucallback` per read type, or reuse for future callbacks?** +The name implies a general callback module. If future non-read callbacks are planned, `UniversalRead` +should probably sit under a broader `UniversalCallbackRecord` umbrella now rather than later. + +--- + +## 10. Cross-team asks + +**Contracts** (`feat-read-state`, pre-merge — cheapest to fix now): +1. `expireExternalRead` refunds nothing — funder's fee is trapped +2. refund `call{value}` + `revert` lets an app with no `receive()` brick its own fulfilment forever +3. `UniversalReadClient` has no `receive()`; `CrossLendMock` adds one privately, so tests pass and the + requirement is invisible to integrators +4. consider marking fulfilled only on callback success (Q3) +5. `chainHeightByChainNamespace` ignores `chainId`, so all `eip155` chains share one height +6. fee derived from requester-controlled `tx.gasprice` +7. **web2 reads are unrequestable** — validation assumes a blockchain (`blockNumber != 0`, non-empty + `owner`, `minConfirmations ≥ 1`) while the UV has a complete web2 executor (Q9). Needs either a + namespace-aware validation branch or an explicit "web2 is not in v1" decision + +**UV team** (#296): +1. `eth_call` transport failures must not become ERROR ballots (Q2) — copy the web2 executor's own + three-way transient/deterministic split +2. confirm the `ucallback` module path (Q1) +3. `uread` deletion once our generated types land diff --git a/api/ucallback/module/v1/module.pulsar.go b/api/ucallback/module/v1/module.pulsar.go new file mode 100644 index 00000000..311612d9 --- /dev/null +++ b/api/ucallback/module/v1/module.pulsar.go @@ -0,0 +1,503 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package modulev1 + +import ( + _ "cosmossdk.io/api/cosmos/app/v1alpha1" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_Module protoreflect.MessageDescriptor +) + +func init() { + file_ucallback_module_v1_module_proto_init() + md_Module = File_ucallback_module_v1_module_proto.Messages().ByName("Module") +} + +var _ protoreflect.Message = (*fastReflection_Module)(nil) + +type fastReflection_Module Module + +func (x *Module) ProtoReflect() protoreflect.Message { + return (*fastReflection_Module)(x) +} + +func (x *Module) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_module_v1_module_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Module_messageType fastReflection_Module_messageType +var _ protoreflect.MessageType = fastReflection_Module_messageType{} + +type fastReflection_Module_messageType struct{} + +func (x fastReflection_Module_messageType) Zero() protoreflect.Message { + return (*fastReflection_Module)(nil) +} +func (x fastReflection_Module_messageType) New() protoreflect.Message { + return new(fastReflection_Module) +} +func (x fastReflection_Module_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Module +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Module) Descriptor() protoreflect.MessageDescriptor { + return md_Module +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Module) Type() protoreflect.MessageType { + return _fastReflection_Module_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Module) New() protoreflect.Message { + return new(fastReflection_Module) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Module) Interface() protoreflect.ProtoMessage { + return (*Module)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Module) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.module.v1.Module")) + } + panic(fmt.Errorf("message ucallback.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.module.v1.Module")) + } + panic(fmt.Errorf("message ucallback.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.module.v1.Module")) + } + panic(fmt.Errorf("message ucallback.module.v1.Module does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.module.v1.Module")) + } + panic(fmt.Errorf("message ucallback.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.module.v1.Module")) + } + panic(fmt.Errorf("message ucallback.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.module.v1.Module")) + } + panic(fmt.Errorf("message ucallback.module.v1.Module does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.module.v1.Module", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Module) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Module) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Module) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Module) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Module) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Module) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: ucallback/module/v1/module.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Module is the app config object of the module. +// Learn more: https://docs.cosmos.network/main/building-modules/depinject +type Module struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Module) Reset() { + *x = Module{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_module_v1_module_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Module) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Module) ProtoMessage() {} + +// Deprecated: Use Module.ProtoReflect.Descriptor instead. +func (*Module) Descriptor() ([]byte, []int) { + return file_ucallback_module_v1_module_proto_rawDescGZIP(), []int{0} +} + +var File_ucallback_module_v1_module_proto protoreflect.FileDescriptor + +var file_ucallback_module_v1_module_proto_rawDesc = []byte{ + 0x0a, 0x20, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x13, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, + 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x36, 0x0a, 0x06, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x3a, 0x2c, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x26, 0x0a, 0x24, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x75, 0x73, 0x68, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x2f, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2d, 0x6e, 0x6f, 0x64, + 0x65, 0x42, 0xdb, 0x01, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x45, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x75, 0x73, 0x68, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x2f, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2d, 0x6e, 0x6f, + 0x64, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, + 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x55, 0x4d, 0x58, 0xaa, 0x02, 0x13, 0x55, 0x63, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, + 0x02, 0x13, 0x55, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5c, 0x4d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1f, 0x55, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, + 0x6b, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x15, 0x55, 0x63, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x3a, 0x3a, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_ucallback_module_v1_module_proto_rawDescOnce sync.Once + file_ucallback_module_v1_module_proto_rawDescData = file_ucallback_module_v1_module_proto_rawDesc +) + +func file_ucallback_module_v1_module_proto_rawDescGZIP() []byte { + file_ucallback_module_v1_module_proto_rawDescOnce.Do(func() { + file_ucallback_module_v1_module_proto_rawDescData = protoimpl.X.CompressGZIP(file_ucallback_module_v1_module_proto_rawDescData) + }) + return file_ucallback_module_v1_module_proto_rawDescData +} + +var file_ucallback_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_ucallback_module_v1_module_proto_goTypes = []interface{}{ + (*Module)(nil), // 0: ucallback.module.v1.Module +} +var file_ucallback_module_v1_module_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_ucallback_module_v1_module_proto_init() } +func file_ucallback_module_v1_module_proto_init() { + if File_ucallback_module_v1_module_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_ucallback_module_v1_module_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Module); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_ucallback_module_v1_module_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_ucallback_module_v1_module_proto_goTypes, + DependencyIndexes: file_ucallback_module_v1_module_proto_depIdxs, + MessageInfos: file_ucallback_module_v1_module_proto_msgTypes, + }.Build() + File_ucallback_module_v1_module_proto = out.File + file_ucallback_module_v1_module_proto_rawDesc = nil + file_ucallback_module_v1_module_proto_goTypes = nil + file_ucallback_module_v1_module_proto_depIdxs = nil +} diff --git a/api/ucallback/v1/genesis.pulsar.go b/api/ucallback/v1/genesis.pulsar.go new file mode 100644 index 00000000..18e19d49 --- /dev/null +++ b/api/ucallback/v1/genesis.pulsar.go @@ -0,0 +1,1779 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package ucallbackv1 + +import ( + _ "cosmossdk.io/api/amino" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "github.com/cosmos/gogoproto/gogoproto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var _ protoreflect.List = (*_GenesisState_2_list)(nil) + +type _GenesisState_2_list struct { + list *[]*UniversalReadEntry +} + +func (x *_GenesisState_2_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_GenesisState_2_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) +} + +func (x *_GenesisState_2_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*UniversalReadEntry) + (*x.list)[i] = concreteValue +} + +func (x *_GenesisState_2_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*UniversalReadEntry) + *x.list = append(*x.list, concreteValue) +} + +func (x *_GenesisState_2_list) AppendMutable() protoreflect.Value { + v := new(UniversalReadEntry) + *x.list = append(*x.list, v) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_GenesisState_2_list) Truncate(n int) { + for i := n; i < len(*x.list); i++ { + (*x.list)[i] = nil + } + *x.list = (*x.list)[:n] +} + +func (x *_GenesisState_2_list) NewElement() protoreflect.Value { + v := new(UniversalReadEntry) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_GenesisState_2_list) IsValid() bool { + return x.list != nil +} + +var ( + md_GenesisState protoreflect.MessageDescriptor + fd_GenesisState_params protoreflect.FieldDescriptor + fd_GenesisState_universal_reads protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_genesis_proto_init() + md_GenesisState = File_ucallback_v1_genesis_proto.Messages().ByName("GenesisState") + fd_GenesisState_params = md_GenesisState.Fields().ByName("params") + fd_GenesisState_universal_reads = md_GenesisState.Fields().ByName("universal_reads") +} + +var _ protoreflect.Message = (*fastReflection_GenesisState)(nil) + +type fastReflection_GenesisState GenesisState + +func (x *GenesisState) ProtoReflect() protoreflect.Message { + return (*fastReflection_GenesisState)(x) +} + +func (x *GenesisState) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_genesis_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_GenesisState_messageType fastReflection_GenesisState_messageType +var _ protoreflect.MessageType = fastReflection_GenesisState_messageType{} + +type fastReflection_GenesisState_messageType struct{} + +func (x fastReflection_GenesisState_messageType) Zero() protoreflect.Message { + return (*fastReflection_GenesisState)(nil) +} +func (x fastReflection_GenesisState_messageType) New() protoreflect.Message { + return new(fastReflection_GenesisState) +} +func (x fastReflection_GenesisState_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_GenesisState +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_GenesisState) Descriptor() protoreflect.MessageDescriptor { + return md_GenesisState +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_GenesisState) Type() protoreflect.MessageType { + return _fastReflection_GenesisState_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_GenesisState) New() protoreflect.Message { + return new(fastReflection_GenesisState) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_GenesisState) Interface() protoreflect.ProtoMessage { + return (*GenesisState)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_GenesisState) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_GenesisState_params, value) { + return + } + } + if len(x.UniversalReads) != 0 { + value := protoreflect.ValueOfList(&_GenesisState_2_list{list: &x.UniversalReads}) + if !f(fd_GenesisState_universal_reads, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_GenesisState) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.GenesisState.params": + return x.Params != nil + case "ucallback.v1.GenesisState.universal_reads": + return len(x.UniversalReads) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.GenesisState")) + } + panic(fmt.Errorf("message ucallback.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_GenesisState) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.GenesisState.params": + x.Params = nil + case "ucallback.v1.GenesisState.universal_reads": + x.UniversalReads = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.GenesisState")) + } + panic(fmt.Errorf("message ucallback.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_GenesisState) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.GenesisState.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "ucallback.v1.GenesisState.universal_reads": + if len(x.UniversalReads) == 0 { + return protoreflect.ValueOfList(&_GenesisState_2_list{}) + } + listValue := &_GenesisState_2_list{list: &x.UniversalReads} + return protoreflect.ValueOfList(listValue) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.GenesisState")) + } + panic(fmt.Errorf("message ucallback.v1.GenesisState does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_GenesisState) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.GenesisState.params": + x.Params = value.Message().Interface().(*Params) + case "ucallback.v1.GenesisState.universal_reads": + lv := value.List() + clv := lv.(*_GenesisState_2_list) + x.UniversalReads = *clv.list + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.GenesisState")) + } + panic(fmt.Errorf("message ucallback.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_GenesisState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.GenesisState.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + case "ucallback.v1.GenesisState.universal_reads": + if x.UniversalReads == nil { + x.UniversalReads = []*UniversalReadEntry{} + } + value := &_GenesisState_2_list{list: &x.UniversalReads} + return protoreflect.ValueOfList(value) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.GenesisState")) + } + panic(fmt.Errorf("message ucallback.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_GenesisState) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.GenesisState.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "ucallback.v1.GenesisState.universal_reads": + list := []*UniversalReadEntry{} + return protoreflect.ValueOfList(&_GenesisState_2_list{list: &list}) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.GenesisState")) + } + panic(fmt.Errorf("message ucallback.v1.GenesisState does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_GenesisState) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.GenesisState", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_GenesisState) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_GenesisState) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_GenesisState) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*GenesisState) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(l)) + } + if len(x.UniversalReads) > 0 { + for _, e := range x.UniversalReads { + l = options.Size(e) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*GenesisState) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.UniversalReads) > 0 { + for iNdEx := len(x.UniversalReads) - 1; iNdEx >= 0; iNdEx-- { + encoded, err := options.Marshal(x.UniversalReads[iNdEx]) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + } + if x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*GenesisState) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field UniversalReads", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.UniversalReads = append(x.UniversalReads, &UniversalReadEntry{}) + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.UniversalReads[len(x.UniversalReads)-1]); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_UniversalReadEntry protoreflect.MessageDescriptor + fd_UniversalReadEntry_key protoreflect.FieldDescriptor + fd_UniversalReadEntry_value protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_genesis_proto_init() + md_UniversalReadEntry = File_ucallback_v1_genesis_proto.Messages().ByName("UniversalReadEntry") + fd_UniversalReadEntry_key = md_UniversalReadEntry.Fields().ByName("key") + fd_UniversalReadEntry_value = md_UniversalReadEntry.Fields().ByName("value") +} + +var _ protoreflect.Message = (*fastReflection_UniversalReadEntry)(nil) + +type fastReflection_UniversalReadEntry UniversalReadEntry + +func (x *UniversalReadEntry) ProtoReflect() protoreflect.Message { + return (*fastReflection_UniversalReadEntry)(x) +} + +func (x *UniversalReadEntry) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_genesis_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_UniversalReadEntry_messageType fastReflection_UniversalReadEntry_messageType +var _ protoreflect.MessageType = fastReflection_UniversalReadEntry_messageType{} + +type fastReflection_UniversalReadEntry_messageType struct{} + +func (x fastReflection_UniversalReadEntry_messageType) Zero() protoreflect.Message { + return (*fastReflection_UniversalReadEntry)(nil) +} +func (x fastReflection_UniversalReadEntry_messageType) New() protoreflect.Message { + return new(fastReflection_UniversalReadEntry) +} +func (x fastReflection_UniversalReadEntry_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_UniversalReadEntry +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_UniversalReadEntry) Descriptor() protoreflect.MessageDescriptor { + return md_UniversalReadEntry +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_UniversalReadEntry) Type() protoreflect.MessageType { + return _fastReflection_UniversalReadEntry_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_UniversalReadEntry) New() protoreflect.Message { + return new(fastReflection_UniversalReadEntry) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_UniversalReadEntry) Interface() protoreflect.ProtoMessage { + return (*UniversalReadEntry)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_UniversalReadEntry) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Key != "" { + value := protoreflect.ValueOfString(x.Key) + if !f(fd_UniversalReadEntry_key, value) { + return + } + } + if x.Value != nil { + value := protoreflect.ValueOfMessage(x.Value.ProtoReflect()) + if !f(fd_UniversalReadEntry_value, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_UniversalReadEntry) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.UniversalReadEntry.key": + return x.Key != "" + case "ucallback.v1.UniversalReadEntry.value": + return x.Value != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.UniversalReadEntry")) + } + panic(fmt.Errorf("message ucallback.v1.UniversalReadEntry does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_UniversalReadEntry) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.UniversalReadEntry.key": + x.Key = "" + case "ucallback.v1.UniversalReadEntry.value": + x.Value = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.UniversalReadEntry")) + } + panic(fmt.Errorf("message ucallback.v1.UniversalReadEntry does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_UniversalReadEntry) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.UniversalReadEntry.key": + value := x.Key + return protoreflect.ValueOfString(value) + case "ucallback.v1.UniversalReadEntry.value": + value := x.Value + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.UniversalReadEntry")) + } + panic(fmt.Errorf("message ucallback.v1.UniversalReadEntry does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_UniversalReadEntry) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.UniversalReadEntry.key": + x.Key = value.Interface().(string) + case "ucallback.v1.UniversalReadEntry.value": + x.Value = value.Message().Interface().(*UniversalRead) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.UniversalReadEntry")) + } + panic(fmt.Errorf("message ucallback.v1.UniversalReadEntry does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_UniversalReadEntry) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.UniversalReadEntry.value": + if x.Value == nil { + x.Value = new(UniversalRead) + } + return protoreflect.ValueOfMessage(x.Value.ProtoReflect()) + case "ucallback.v1.UniversalReadEntry.key": + panic(fmt.Errorf("field key of message ucallback.v1.UniversalReadEntry is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.UniversalReadEntry")) + } + panic(fmt.Errorf("message ucallback.v1.UniversalReadEntry does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_UniversalReadEntry) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.UniversalReadEntry.key": + return protoreflect.ValueOfString("") + case "ucallback.v1.UniversalReadEntry.value": + m := new(UniversalRead) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.UniversalReadEntry")) + } + panic(fmt.Errorf("message ucallback.v1.UniversalReadEntry does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_UniversalReadEntry) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.UniversalReadEntry", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_UniversalReadEntry) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_UniversalReadEntry) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_UniversalReadEntry) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_UniversalReadEntry) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*UniversalReadEntry) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Key) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Value != nil { + l = options.Size(x.Value) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*UniversalReadEntry) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Value != nil { + encoded, err := options.Marshal(x.Value) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if len(x.Key) > 0 { + i -= len(x.Key) + copy(dAtA[i:], x.Key) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Key))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*UniversalReadEntry) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: UniversalReadEntry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: UniversalReadEntry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Key = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Value == nil { + x.Value = &UniversalRead{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Value); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_Params protoreflect.MessageDescriptor + fd_Params_some_value protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_genesis_proto_init() + md_Params = File_ucallback_v1_genesis_proto.Messages().ByName("Params") + fd_Params_some_value = md_Params.Fields().ByName("some_value") +} + +var _ protoreflect.Message = (*fastReflection_Params)(nil) + +type fastReflection_Params Params + +func (x *Params) ProtoReflect() protoreflect.Message { + return (*fastReflection_Params)(x) +} + +func (x *Params) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_genesis_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_Params_messageType fastReflection_Params_messageType +var _ protoreflect.MessageType = fastReflection_Params_messageType{} + +type fastReflection_Params_messageType struct{} + +func (x fastReflection_Params_messageType) Zero() protoreflect.Message { + return (*fastReflection_Params)(nil) +} +func (x fastReflection_Params_messageType) New() protoreflect.Message { + return new(fastReflection_Params) +} +func (x fastReflection_Params_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Params +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Params) Descriptor() protoreflect.MessageDescriptor { + return md_Params +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_Params) Type() protoreflect.MessageType { + return _fastReflection_Params_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Params) New() protoreflect.Message { + return new(fastReflection_Params) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Params) Interface() protoreflect.ProtoMessage { + return (*Params)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.SomeValue != false { + value := protoreflect.ValueOfBool(x.SomeValue) + if !f(fd_Params_some_value, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.Params.some_value": + return x.SomeValue != false + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.Params")) + } + panic(fmt.Errorf("message ucallback.v1.Params does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.Params.some_value": + x.SomeValue = false + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.Params")) + } + panic(fmt.Errorf("message ucallback.v1.Params does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.Params.some_value": + value := x.SomeValue + return protoreflect.ValueOfBool(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.Params")) + } + panic(fmt.Errorf("message ucallback.v1.Params does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.Params.some_value": + x.SomeValue = value.Bool() + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.Params")) + } + panic(fmt.Errorf("message ucallback.v1.Params does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.Params.some_value": + panic(fmt.Errorf("field some_value of message ucallback.v1.Params is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.Params")) + } + panic(fmt.Errorf("message ucallback.v1.Params does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.Params.some_value": + return protoreflect.ValueOfBool(false) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.Params")) + } + panic(fmt.Errorf("message ucallback.v1.Params does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_Params) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.Params", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_Params) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_Params) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_Params) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_Params) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Params) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.SomeValue { + n += 2 + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*Params) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.SomeValue { + i-- + if x.SomeValue { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*Params) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field SomeValue", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + x.SomeValue = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: ucallback/v1/genesis.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// GenesisState defines the module genesis state +type GenesisState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Params defines all the parameters of the module. + Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` + // universal_reads are key-value pairs from the UniversalReads map. + // + // Only the canonical records are exported. PendingByExpiry and ReadsByTxHash + // are indexes derived from these, and are rebuilt during InitGenesis rather + // than exported — so they cannot be imported out of sync with the records they + // point at. + UniversalReads []*UniversalReadEntry `protobuf:"bytes,2,rep,name=universal_reads,json=universalReads,proto3" json:"universal_reads,omitempty"` +} + +func (x *GenesisState) Reset() { + *x = GenesisState{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_genesis_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GenesisState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenesisState) ProtoMessage() {} + +// Deprecated: Use GenesisState.ProtoReflect.Descriptor instead. +func (*GenesisState) Descriptor() ([]byte, []int) { + return file_ucallback_v1_genesis_proto_rawDescGZIP(), []int{0} +} + +func (x *GenesisState) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +func (x *GenesisState) GetUniversalReads() []*UniversalReadEntry { + if x != nil { + return x.UniversalReads + } + return nil +} + +// UniversalReadEntry is one key-value pair from the UniversalReads map. +type UniversalReadEntry struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value *UniversalRead `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *UniversalReadEntry) Reset() { + *x = UniversalReadEntry{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_genesis_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UniversalReadEntry) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UniversalReadEntry) ProtoMessage() {} + +// Deprecated: Use UniversalReadEntry.ProtoReflect.Descriptor instead. +func (*UniversalReadEntry) Descriptor() ([]byte, []int) { + return file_ucallback_v1_genesis_proto_rawDescGZIP(), []int{1} +} + +func (x *UniversalReadEntry) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *UniversalReadEntry) GetValue() *UniversalRead { + if x != nil { + return x.Value + } + return nil +} + +// Params defines the set of module parameters. +type Params struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SomeValue bool `protobuf:"varint,2,opt,name=some_value,json=someValue,proto3" json:"some_value,omitempty"` +} + +func (x *Params) Reset() { + *x = Params{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_genesis_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Params) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Params) ProtoMessage() {} + +// Deprecated: Use Params.ProtoReflect.Descriptor instead. +func (*Params) Descriptor() ([]byte, []int) { + return file_ucallback_v1_genesis_proto_rawDescGZIP(), []int{2} +} + +func (x *Params) GetSomeValue() bool { + if x != nil { + return x.SomeValue + } + return false +} + +var File_ucallback_v1_genesis_proto protoreflect.FileDescriptor + +var file_ucallback_v1_genesis_proto_rawDesc = []byte{ + 0x0a, 0x1a, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x67, + 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x75, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x18, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x76, + 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x93, 0x01, + 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x32, + 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, + 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x12, 0x4f, 0x0a, 0x0f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x5f, + 0x72, 0x65, 0x61, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x75, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x04, 0xc8, + 0xde, 0x1f, 0x00, 0x52, 0x0e, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x52, 0x65, + 0x61, 0x64, 0x73, 0x22, 0x5f, 0x0a, 0x12, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, + 0x52, 0x65, 0x61, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x75, 0x63, 0x61, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x22, 0x46, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1d, + 0x0a, 0x0a, 0x73, 0x6f, 0x6d, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x09, 0x73, 0x6f, 0x6d, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x1d, 0x98, + 0xa0, 0x1f, 0x00, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, 0x2a, 0x10, 0x75, 0x63, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0xb4, 0x01, 0x0a, + 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, + 0x31, 0x42, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x75, + 0x73, 0x68, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x75, 0x63, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, + 0x63, 0x6b, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x55, 0x58, 0x58, 0xaa, 0x02, 0x0c, 0x55, 0x63, 0x61, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0c, 0x55, 0x63, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x18, 0x55, 0x63, 0x61, 0x6c, 0x6c, + 0x62, 0x61, 0x63, 0x6b, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0xea, 0x02, 0x0d, 0x55, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x3a, + 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_ucallback_v1_genesis_proto_rawDescOnce sync.Once + file_ucallback_v1_genesis_proto_rawDescData = file_ucallback_v1_genesis_proto_rawDesc +) + +func file_ucallback_v1_genesis_proto_rawDescGZIP() []byte { + file_ucallback_v1_genesis_proto_rawDescOnce.Do(func() { + file_ucallback_v1_genesis_proto_rawDescData = protoimpl.X.CompressGZIP(file_ucallback_v1_genesis_proto_rawDescData) + }) + return file_ucallback_v1_genesis_proto_rawDescData +} + +var file_ucallback_v1_genesis_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_ucallback_v1_genesis_proto_goTypes = []interface{}{ + (*GenesisState)(nil), // 0: ucallback.v1.GenesisState + (*UniversalReadEntry)(nil), // 1: ucallback.v1.UniversalReadEntry + (*Params)(nil), // 2: ucallback.v1.Params + (*UniversalRead)(nil), // 3: ucallback.v1.UniversalRead +} +var file_ucallback_v1_genesis_proto_depIdxs = []int32{ + 2, // 0: ucallback.v1.GenesisState.params:type_name -> ucallback.v1.Params + 1, // 1: ucallback.v1.GenesisState.universal_reads:type_name -> ucallback.v1.UniversalReadEntry + 3, // 2: ucallback.v1.UniversalReadEntry.value:type_name -> ucallback.v1.UniversalRead + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_ucallback_v1_genesis_proto_init() } +func file_ucallback_v1_genesis_proto_init() { + if File_ucallback_v1_genesis_proto != nil { + return + } + file_ucallback_v1_types_proto_init() + if !protoimpl.UnsafeEnabled { + file_ucallback_v1_genesis_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GenesisState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_genesis_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UniversalReadEntry); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_genesis_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Params); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_ucallback_v1_genesis_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_ucallback_v1_genesis_proto_goTypes, + DependencyIndexes: file_ucallback_v1_genesis_proto_depIdxs, + MessageInfos: file_ucallback_v1_genesis_proto_msgTypes, + }.Build() + File_ucallback_v1_genesis_proto = out.File + file_ucallback_v1_genesis_proto_rawDesc = nil + file_ucallback_v1_genesis_proto_goTypes = nil + file_ucallback_v1_genesis_proto_depIdxs = nil +} diff --git a/api/ucallback/v1/query.pulsar.go b/api/ucallback/v1/query.pulsar.go new file mode 100644 index 00000000..d0a8203f --- /dev/null +++ b/api/ucallback/v1/query.pulsar.go @@ -0,0 +1,4163 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package ucallbackv1 + +import ( + v1beta1 "cosmossdk.io/api/cosmos/base/query/v1beta1" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "github.com/cosmos/gogoproto/gogoproto" + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_QueryParamsRequest protoreflect.MessageDescriptor +) + +func init() { + file_ucallback_v1_query_proto_init() + md_QueryParamsRequest = File_ucallback_v1_query_proto.Messages().ByName("QueryParamsRequest") +} + +var _ protoreflect.Message = (*fastReflection_QueryParamsRequest)(nil) + +type fastReflection_QueryParamsRequest QueryParamsRequest + +func (x *QueryParamsRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryParamsRequest)(x) +} + +func (x *QueryParamsRequest) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_query_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryParamsRequest_messageType fastReflection_QueryParamsRequest_messageType +var _ protoreflect.MessageType = fastReflection_QueryParamsRequest_messageType{} + +type fastReflection_QueryParamsRequest_messageType struct{} + +func (x fastReflection_QueryParamsRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryParamsRequest)(nil) +} +func (x fastReflection_QueryParamsRequest_messageType) New() protoreflect.Message { + return new(fastReflection_QueryParamsRequest) +} +func (x fastReflection_QueryParamsRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsRequest +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryParamsRequest) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsRequest +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryParamsRequest) Type() protoreflect.MessageType { + return _fastReflection_QueryParamsRequest_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryParamsRequest) New() protoreflect.Message { + return new(fastReflection_QueryParamsRequest) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryParamsRequest) Interface() protoreflect.ProtoMessage { + return (*QueryParamsRequest)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryParamsRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryParamsRequest) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsRequest) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryParamsRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryParamsRequest does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryParamsRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryParamsRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.QueryParamsRequest", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryParamsRequest) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsRequest) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryParamsRequest) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryParamsRequest) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryParamsRequest) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryParamsRequest) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryParamsRequest) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_QueryParamsResponse protoreflect.MessageDescriptor + fd_QueryParamsResponse_params protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_query_proto_init() + md_QueryParamsResponse = File_ucallback_v1_query_proto.Messages().ByName("QueryParamsResponse") + fd_QueryParamsResponse_params = md_QueryParamsResponse.Fields().ByName("params") +} + +var _ protoreflect.Message = (*fastReflection_QueryParamsResponse)(nil) + +type fastReflection_QueryParamsResponse QueryParamsResponse + +func (x *QueryParamsResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryParamsResponse)(x) +} + +func (x *QueryParamsResponse) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_query_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryParamsResponse_messageType fastReflection_QueryParamsResponse_messageType +var _ protoreflect.MessageType = fastReflection_QueryParamsResponse_messageType{} + +type fastReflection_QueryParamsResponse_messageType struct{} + +func (x fastReflection_QueryParamsResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryParamsResponse)(nil) +} +func (x fastReflection_QueryParamsResponse_messageType) New() protoreflect.Message { + return new(fastReflection_QueryParamsResponse) +} +func (x fastReflection_QueryParamsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryParamsResponse) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryParamsResponse) Type() protoreflect.MessageType { + return _fastReflection_QueryParamsResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryParamsResponse) New() protoreflect.Message { + return new(fastReflection_QueryParamsResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryParamsResponse) Interface() protoreflect.ProtoMessage { + return (*QueryParamsResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryParamsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_QueryParamsResponse_params, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.QueryParamsResponse.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.QueryParamsResponse.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.QueryParamsResponse.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryParamsResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.QueryParamsResponse.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryParamsResponse.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryParamsResponse.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.QueryParamsResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryParamsResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryParamsResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryParamsResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryParamsResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryParamsResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryParamsResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryParamsResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_QueryAllPendingReadRequestsRequest protoreflect.MessageDescriptor + fd_QueryAllPendingReadRequestsRequest_pagination protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_query_proto_init() + md_QueryAllPendingReadRequestsRequest = File_ucallback_v1_query_proto.Messages().ByName("QueryAllPendingReadRequestsRequest") + fd_QueryAllPendingReadRequestsRequest_pagination = md_QueryAllPendingReadRequestsRequest.Fields().ByName("pagination") +} + +var _ protoreflect.Message = (*fastReflection_QueryAllPendingReadRequestsRequest)(nil) + +type fastReflection_QueryAllPendingReadRequestsRequest QueryAllPendingReadRequestsRequest + +func (x *QueryAllPendingReadRequestsRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryAllPendingReadRequestsRequest)(x) +} + +func (x *QueryAllPendingReadRequestsRequest) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_query_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryAllPendingReadRequestsRequest_messageType fastReflection_QueryAllPendingReadRequestsRequest_messageType +var _ protoreflect.MessageType = fastReflection_QueryAllPendingReadRequestsRequest_messageType{} + +type fastReflection_QueryAllPendingReadRequestsRequest_messageType struct{} + +func (x fastReflection_QueryAllPendingReadRequestsRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryAllPendingReadRequestsRequest)(nil) +} +func (x fastReflection_QueryAllPendingReadRequestsRequest_messageType) New() protoreflect.Message { + return new(fastReflection_QueryAllPendingReadRequestsRequest) +} +func (x fastReflection_QueryAllPendingReadRequestsRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryAllPendingReadRequestsRequest +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) Descriptor() protoreflect.MessageDescriptor { + return md_QueryAllPendingReadRequestsRequest +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) Type() protoreflect.MessageType { + return _fastReflection_QueryAllPendingReadRequestsRequest_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) New() protoreflect.Message { + return new(fastReflection_QueryAllPendingReadRequestsRequest) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) Interface() protoreflect.ProtoMessage { + return (*QueryAllPendingReadRequestsRequest)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Pagination != nil { + value := protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) + if !f(fd_QueryAllPendingReadRequestsRequest_pagination, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.QueryAllPendingReadRequestsRequest.pagination": + return x.Pagination != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryAllPendingReadRequestsRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryAllPendingReadRequestsRequest does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.QueryAllPendingReadRequestsRequest.pagination": + x.Pagination = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryAllPendingReadRequestsRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryAllPendingReadRequestsRequest does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.QueryAllPendingReadRequestsRequest.pagination": + value := x.Pagination + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryAllPendingReadRequestsRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryAllPendingReadRequestsRequest does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.QueryAllPendingReadRequestsRequest.pagination": + x.Pagination = value.Message().Interface().(*v1beta1.PageRequest) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryAllPendingReadRequestsRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryAllPendingReadRequestsRequest does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryAllPendingReadRequestsRequest.pagination": + if x.Pagination == nil { + x.Pagination = new(v1beta1.PageRequest) + } + return protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryAllPendingReadRequestsRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryAllPendingReadRequestsRequest does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryAllPendingReadRequestsRequest.pagination": + m := new(v1beta1.PageRequest) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryAllPendingReadRequestsRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryAllPendingReadRequestsRequest does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.QueryAllPendingReadRequestsRequest", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryAllPendingReadRequestsRequest) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryAllPendingReadRequestsRequest) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Pagination != nil { + l = options.Size(x.Pagination) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryAllPendingReadRequestsRequest) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Pagination != nil { + encoded, err := options.Marshal(x.Pagination) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryAllPendingReadRequestsRequest) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryAllPendingReadRequestsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryAllPendingReadRequestsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Pagination == nil { + x.Pagination = &v1beta1.PageRequest{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Pagination); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var _ protoreflect.List = (*_QueryAllPendingReadRequestsResponse_1_list)(nil) + +type _QueryAllPendingReadRequestsResponse_1_list struct { + list *[]*UniversalRead +} + +func (x *_QueryAllPendingReadRequestsResponse_1_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_QueryAllPendingReadRequestsResponse_1_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) +} + +func (x *_QueryAllPendingReadRequestsResponse_1_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*UniversalRead) + (*x.list)[i] = concreteValue +} + +func (x *_QueryAllPendingReadRequestsResponse_1_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*UniversalRead) + *x.list = append(*x.list, concreteValue) +} + +func (x *_QueryAllPendingReadRequestsResponse_1_list) AppendMutable() protoreflect.Value { + v := new(UniversalRead) + *x.list = append(*x.list, v) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_QueryAllPendingReadRequestsResponse_1_list) Truncate(n int) { + for i := n; i < len(*x.list); i++ { + (*x.list)[i] = nil + } + *x.list = (*x.list)[:n] +} + +func (x *_QueryAllPendingReadRequestsResponse_1_list) NewElement() protoreflect.Value { + v := new(UniversalRead) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_QueryAllPendingReadRequestsResponse_1_list) IsValid() bool { + return x.list != nil +} + +var ( + md_QueryAllPendingReadRequestsResponse protoreflect.MessageDescriptor + fd_QueryAllPendingReadRequestsResponse_reads protoreflect.FieldDescriptor + fd_QueryAllPendingReadRequestsResponse_pagination protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_query_proto_init() + md_QueryAllPendingReadRequestsResponse = File_ucallback_v1_query_proto.Messages().ByName("QueryAllPendingReadRequestsResponse") + fd_QueryAllPendingReadRequestsResponse_reads = md_QueryAllPendingReadRequestsResponse.Fields().ByName("reads") + fd_QueryAllPendingReadRequestsResponse_pagination = md_QueryAllPendingReadRequestsResponse.Fields().ByName("pagination") +} + +var _ protoreflect.Message = (*fastReflection_QueryAllPendingReadRequestsResponse)(nil) + +type fastReflection_QueryAllPendingReadRequestsResponse QueryAllPendingReadRequestsResponse + +func (x *QueryAllPendingReadRequestsResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryAllPendingReadRequestsResponse)(x) +} + +func (x *QueryAllPendingReadRequestsResponse) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_query_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryAllPendingReadRequestsResponse_messageType fastReflection_QueryAllPendingReadRequestsResponse_messageType +var _ protoreflect.MessageType = fastReflection_QueryAllPendingReadRequestsResponse_messageType{} + +type fastReflection_QueryAllPendingReadRequestsResponse_messageType struct{} + +func (x fastReflection_QueryAllPendingReadRequestsResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryAllPendingReadRequestsResponse)(nil) +} +func (x fastReflection_QueryAllPendingReadRequestsResponse_messageType) New() protoreflect.Message { + return new(fastReflection_QueryAllPendingReadRequestsResponse) +} +func (x fastReflection_QueryAllPendingReadRequestsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryAllPendingReadRequestsResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) Descriptor() protoreflect.MessageDescriptor { + return md_QueryAllPendingReadRequestsResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) Type() protoreflect.MessageType { + return _fastReflection_QueryAllPendingReadRequestsResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) New() protoreflect.Message { + return new(fastReflection_QueryAllPendingReadRequestsResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) Interface() protoreflect.ProtoMessage { + return (*QueryAllPendingReadRequestsResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.Reads) != 0 { + value := protoreflect.ValueOfList(&_QueryAllPendingReadRequestsResponse_1_list{list: &x.Reads}) + if !f(fd_QueryAllPendingReadRequestsResponse_reads, value) { + return + } + } + if x.Pagination != nil { + value := protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) + if !f(fd_QueryAllPendingReadRequestsResponse_pagination, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.QueryAllPendingReadRequestsResponse.reads": + return len(x.Reads) != 0 + case "ucallback.v1.QueryAllPendingReadRequestsResponse.pagination": + return x.Pagination != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryAllPendingReadRequestsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryAllPendingReadRequestsResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.QueryAllPendingReadRequestsResponse.reads": + x.Reads = nil + case "ucallback.v1.QueryAllPendingReadRequestsResponse.pagination": + x.Pagination = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryAllPendingReadRequestsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryAllPendingReadRequestsResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.QueryAllPendingReadRequestsResponse.reads": + if len(x.Reads) == 0 { + return protoreflect.ValueOfList(&_QueryAllPendingReadRequestsResponse_1_list{}) + } + listValue := &_QueryAllPendingReadRequestsResponse_1_list{list: &x.Reads} + return protoreflect.ValueOfList(listValue) + case "ucallback.v1.QueryAllPendingReadRequestsResponse.pagination": + value := x.Pagination + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryAllPendingReadRequestsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryAllPendingReadRequestsResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.QueryAllPendingReadRequestsResponse.reads": + lv := value.List() + clv := lv.(*_QueryAllPendingReadRequestsResponse_1_list) + x.Reads = *clv.list + case "ucallback.v1.QueryAllPendingReadRequestsResponse.pagination": + x.Pagination = value.Message().Interface().(*v1beta1.PageResponse) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryAllPendingReadRequestsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryAllPendingReadRequestsResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryAllPendingReadRequestsResponse.reads": + if x.Reads == nil { + x.Reads = []*UniversalRead{} + } + value := &_QueryAllPendingReadRequestsResponse_1_list{list: &x.Reads} + return protoreflect.ValueOfList(value) + case "ucallback.v1.QueryAllPendingReadRequestsResponse.pagination": + if x.Pagination == nil { + x.Pagination = new(v1beta1.PageResponse) + } + return protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryAllPendingReadRequestsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryAllPendingReadRequestsResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryAllPendingReadRequestsResponse.reads": + list := []*UniversalRead{} + return protoreflect.ValueOfList(&_QueryAllPendingReadRequestsResponse_1_list{list: &list}) + case "ucallback.v1.QueryAllPendingReadRequestsResponse.pagination": + m := new(v1beta1.PageResponse) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryAllPendingReadRequestsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryAllPendingReadRequestsResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.QueryAllPendingReadRequestsResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryAllPendingReadRequestsResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryAllPendingReadRequestsResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if len(x.Reads) > 0 { + for _, e := range x.Reads { + l = options.Size(e) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.Pagination != nil { + l = options.Size(x.Pagination) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryAllPendingReadRequestsResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Pagination != nil { + encoded, err := options.Marshal(x.Pagination) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if len(x.Reads) > 0 { + for iNdEx := len(x.Reads) - 1; iNdEx >= 0; iNdEx-- { + encoded, err := options.Marshal(x.Reads[iNdEx]) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryAllPendingReadRequestsResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryAllPendingReadRequestsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryAllPendingReadRequestsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Reads", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Reads = append(x.Reads, &UniversalRead{}) + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Reads[len(x.Reads)-1]); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Pagination == nil { + x.Pagination = &v1beta1.PageResponse{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Pagination); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_QueryUniversalReadRequest protoreflect.MessageDescriptor + fd_QueryUniversalReadRequest_request_id protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_query_proto_init() + md_QueryUniversalReadRequest = File_ucallback_v1_query_proto.Messages().ByName("QueryUniversalReadRequest") + fd_QueryUniversalReadRequest_request_id = md_QueryUniversalReadRequest.Fields().ByName("request_id") +} + +var _ protoreflect.Message = (*fastReflection_QueryUniversalReadRequest)(nil) + +type fastReflection_QueryUniversalReadRequest QueryUniversalReadRequest + +func (x *QueryUniversalReadRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryUniversalReadRequest)(x) +} + +func (x *QueryUniversalReadRequest) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_query_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryUniversalReadRequest_messageType fastReflection_QueryUniversalReadRequest_messageType +var _ protoreflect.MessageType = fastReflection_QueryUniversalReadRequest_messageType{} + +type fastReflection_QueryUniversalReadRequest_messageType struct{} + +func (x fastReflection_QueryUniversalReadRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryUniversalReadRequest)(nil) +} +func (x fastReflection_QueryUniversalReadRequest_messageType) New() protoreflect.Message { + return new(fastReflection_QueryUniversalReadRequest) +} +func (x fastReflection_QueryUniversalReadRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryUniversalReadRequest +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryUniversalReadRequest) Descriptor() protoreflect.MessageDescriptor { + return md_QueryUniversalReadRequest +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryUniversalReadRequest) Type() protoreflect.MessageType { + return _fastReflection_QueryUniversalReadRequest_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryUniversalReadRequest) New() protoreflect.Message { + return new(fastReflection_QueryUniversalReadRequest) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryUniversalReadRequest) Interface() protoreflect.ProtoMessage { + return (*QueryUniversalReadRequest)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryUniversalReadRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.RequestId != "" { + value := protoreflect.ValueOfString(x.RequestId) + if !f(fd_QueryUniversalReadRequest_request_id, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryUniversalReadRequest) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.QueryUniversalReadRequest.request_id": + return x.RequestId != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryUniversalReadRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryUniversalReadRequest does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryUniversalReadRequest) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.QueryUniversalReadRequest.request_id": + x.RequestId = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryUniversalReadRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryUniversalReadRequest does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryUniversalReadRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.QueryUniversalReadRequest.request_id": + value := x.RequestId + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryUniversalReadRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryUniversalReadRequest does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryUniversalReadRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.QueryUniversalReadRequest.request_id": + x.RequestId = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryUniversalReadRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryUniversalReadRequest does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryUniversalReadRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryUniversalReadRequest.request_id": + panic(fmt.Errorf("field request_id of message ucallback.v1.QueryUniversalReadRequest is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryUniversalReadRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryUniversalReadRequest does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryUniversalReadRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryUniversalReadRequest.request_id": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryUniversalReadRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryUniversalReadRequest does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryUniversalReadRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.QueryUniversalReadRequest", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryUniversalReadRequest) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryUniversalReadRequest) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryUniversalReadRequest) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryUniversalReadRequest) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryUniversalReadRequest) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.RequestId) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryUniversalReadRequest) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.RequestId) > 0 { + i -= len(x.RequestId) + copy(dAtA[i:], x.RequestId) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.RequestId))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryUniversalReadRequest) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryUniversalReadRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryUniversalReadRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field RequestId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.RequestId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_QueryUniversalReadResponse protoreflect.MessageDescriptor + fd_QueryUniversalReadResponse_read protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_query_proto_init() + md_QueryUniversalReadResponse = File_ucallback_v1_query_proto.Messages().ByName("QueryUniversalReadResponse") + fd_QueryUniversalReadResponse_read = md_QueryUniversalReadResponse.Fields().ByName("read") +} + +var _ protoreflect.Message = (*fastReflection_QueryUniversalReadResponse)(nil) + +type fastReflection_QueryUniversalReadResponse QueryUniversalReadResponse + +func (x *QueryUniversalReadResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryUniversalReadResponse)(x) +} + +func (x *QueryUniversalReadResponse) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_query_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryUniversalReadResponse_messageType fastReflection_QueryUniversalReadResponse_messageType +var _ protoreflect.MessageType = fastReflection_QueryUniversalReadResponse_messageType{} + +type fastReflection_QueryUniversalReadResponse_messageType struct{} + +func (x fastReflection_QueryUniversalReadResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryUniversalReadResponse)(nil) +} +func (x fastReflection_QueryUniversalReadResponse_messageType) New() protoreflect.Message { + return new(fastReflection_QueryUniversalReadResponse) +} +func (x fastReflection_QueryUniversalReadResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryUniversalReadResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryUniversalReadResponse) Descriptor() protoreflect.MessageDescriptor { + return md_QueryUniversalReadResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryUniversalReadResponse) Type() protoreflect.MessageType { + return _fastReflection_QueryUniversalReadResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryUniversalReadResponse) New() protoreflect.Message { + return new(fastReflection_QueryUniversalReadResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryUniversalReadResponse) Interface() protoreflect.ProtoMessage { + return (*QueryUniversalReadResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryUniversalReadResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Read != nil { + value := protoreflect.ValueOfMessage(x.Read.ProtoReflect()) + if !f(fd_QueryUniversalReadResponse_read, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryUniversalReadResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.QueryUniversalReadResponse.read": + return x.Read != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryUniversalReadResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryUniversalReadResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryUniversalReadResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.QueryUniversalReadResponse.read": + x.Read = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryUniversalReadResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryUniversalReadResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryUniversalReadResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.QueryUniversalReadResponse.read": + value := x.Read + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryUniversalReadResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryUniversalReadResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryUniversalReadResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.QueryUniversalReadResponse.read": + x.Read = value.Message().Interface().(*UniversalRead) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryUniversalReadResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryUniversalReadResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryUniversalReadResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryUniversalReadResponse.read": + if x.Read == nil { + x.Read = new(UniversalRead) + } + return protoreflect.ValueOfMessage(x.Read.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryUniversalReadResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryUniversalReadResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryUniversalReadResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryUniversalReadResponse.read": + m := new(UniversalRead) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryUniversalReadResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryUniversalReadResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryUniversalReadResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.QueryUniversalReadResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryUniversalReadResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryUniversalReadResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryUniversalReadResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryUniversalReadResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryUniversalReadResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Read != nil { + l = options.Size(x.Read) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryUniversalReadResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Read != nil { + encoded, err := options.Marshal(x.Read) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryUniversalReadResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryUniversalReadResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryUniversalReadResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Read", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Read == nil { + x.Read = &UniversalRead{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Read); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_QueryReadsByTxRequest protoreflect.MessageDescriptor + fd_QueryReadsByTxRequest_tx_hash protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_query_proto_init() + md_QueryReadsByTxRequest = File_ucallback_v1_query_proto.Messages().ByName("QueryReadsByTxRequest") + fd_QueryReadsByTxRequest_tx_hash = md_QueryReadsByTxRequest.Fields().ByName("tx_hash") +} + +var _ protoreflect.Message = (*fastReflection_QueryReadsByTxRequest)(nil) + +type fastReflection_QueryReadsByTxRequest QueryReadsByTxRequest + +func (x *QueryReadsByTxRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryReadsByTxRequest)(x) +} + +func (x *QueryReadsByTxRequest) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_query_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryReadsByTxRequest_messageType fastReflection_QueryReadsByTxRequest_messageType +var _ protoreflect.MessageType = fastReflection_QueryReadsByTxRequest_messageType{} + +type fastReflection_QueryReadsByTxRequest_messageType struct{} + +func (x fastReflection_QueryReadsByTxRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryReadsByTxRequest)(nil) +} +func (x fastReflection_QueryReadsByTxRequest_messageType) New() protoreflect.Message { + return new(fastReflection_QueryReadsByTxRequest) +} +func (x fastReflection_QueryReadsByTxRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryReadsByTxRequest +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryReadsByTxRequest) Descriptor() protoreflect.MessageDescriptor { + return md_QueryReadsByTxRequest +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryReadsByTxRequest) Type() protoreflect.MessageType { + return _fastReflection_QueryReadsByTxRequest_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryReadsByTxRequest) New() protoreflect.Message { + return new(fastReflection_QueryReadsByTxRequest) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryReadsByTxRequest) Interface() protoreflect.ProtoMessage { + return (*QueryReadsByTxRequest)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryReadsByTxRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.TxHash != "" { + value := protoreflect.ValueOfString(x.TxHash) + if !f(fd_QueryReadsByTxRequest_tx_hash, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryReadsByTxRequest) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.QueryReadsByTxRequest.tx_hash": + return x.TxHash != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryReadsByTxRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryReadsByTxRequest does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryReadsByTxRequest) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.QueryReadsByTxRequest.tx_hash": + x.TxHash = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryReadsByTxRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryReadsByTxRequest does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryReadsByTxRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.QueryReadsByTxRequest.tx_hash": + value := x.TxHash + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryReadsByTxRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryReadsByTxRequest does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryReadsByTxRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.QueryReadsByTxRequest.tx_hash": + x.TxHash = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryReadsByTxRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryReadsByTxRequest does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryReadsByTxRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryReadsByTxRequest.tx_hash": + panic(fmt.Errorf("field tx_hash of message ucallback.v1.QueryReadsByTxRequest is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryReadsByTxRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryReadsByTxRequest does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryReadsByTxRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryReadsByTxRequest.tx_hash": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryReadsByTxRequest")) + } + panic(fmt.Errorf("message ucallback.v1.QueryReadsByTxRequest does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryReadsByTxRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.QueryReadsByTxRequest", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryReadsByTxRequest) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryReadsByTxRequest) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryReadsByTxRequest) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryReadsByTxRequest) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryReadsByTxRequest) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.TxHash) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryReadsByTxRequest) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.TxHash) > 0 { + i -= len(x.TxHash) + copy(dAtA[i:], x.TxHash) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.TxHash))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryReadsByTxRequest) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryReadsByTxRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryReadsByTxRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field TxHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.TxHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var _ protoreflect.List = (*_QueryReadsByTxResponse_1_list)(nil) + +type _QueryReadsByTxResponse_1_list struct { + list *[]*UniversalRead +} + +func (x *_QueryReadsByTxResponse_1_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_QueryReadsByTxResponse_1_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) +} + +func (x *_QueryReadsByTxResponse_1_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*UniversalRead) + (*x.list)[i] = concreteValue +} + +func (x *_QueryReadsByTxResponse_1_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*UniversalRead) + *x.list = append(*x.list, concreteValue) +} + +func (x *_QueryReadsByTxResponse_1_list) AppendMutable() protoreflect.Value { + v := new(UniversalRead) + *x.list = append(*x.list, v) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_QueryReadsByTxResponse_1_list) Truncate(n int) { + for i := n; i < len(*x.list); i++ { + (*x.list)[i] = nil + } + *x.list = (*x.list)[:n] +} + +func (x *_QueryReadsByTxResponse_1_list) NewElement() protoreflect.Value { + v := new(UniversalRead) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_QueryReadsByTxResponse_1_list) IsValid() bool { + return x.list != nil +} + +var ( + md_QueryReadsByTxResponse protoreflect.MessageDescriptor + fd_QueryReadsByTxResponse_reads protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_query_proto_init() + md_QueryReadsByTxResponse = File_ucallback_v1_query_proto.Messages().ByName("QueryReadsByTxResponse") + fd_QueryReadsByTxResponse_reads = md_QueryReadsByTxResponse.Fields().ByName("reads") +} + +var _ protoreflect.Message = (*fastReflection_QueryReadsByTxResponse)(nil) + +type fastReflection_QueryReadsByTxResponse QueryReadsByTxResponse + +func (x *QueryReadsByTxResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryReadsByTxResponse)(x) +} + +func (x *QueryReadsByTxResponse) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_query_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_QueryReadsByTxResponse_messageType fastReflection_QueryReadsByTxResponse_messageType +var _ protoreflect.MessageType = fastReflection_QueryReadsByTxResponse_messageType{} + +type fastReflection_QueryReadsByTxResponse_messageType struct{} + +func (x fastReflection_QueryReadsByTxResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryReadsByTxResponse)(nil) +} +func (x fastReflection_QueryReadsByTxResponse_messageType) New() protoreflect.Message { + return new(fastReflection_QueryReadsByTxResponse) +} +func (x fastReflection_QueryReadsByTxResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryReadsByTxResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryReadsByTxResponse) Descriptor() protoreflect.MessageDescriptor { + return md_QueryReadsByTxResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_QueryReadsByTxResponse) Type() protoreflect.MessageType { + return _fastReflection_QueryReadsByTxResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryReadsByTxResponse) New() protoreflect.Message { + return new(fastReflection_QueryReadsByTxResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryReadsByTxResponse) Interface() protoreflect.ProtoMessage { + return (*QueryReadsByTxResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_QueryReadsByTxResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.Reads) != 0 { + value := protoreflect.ValueOfList(&_QueryReadsByTxResponse_1_list{list: &x.Reads}) + if !f(fd_QueryReadsByTxResponse_reads, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_QueryReadsByTxResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.QueryReadsByTxResponse.reads": + return len(x.Reads) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryReadsByTxResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryReadsByTxResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryReadsByTxResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.QueryReadsByTxResponse.reads": + x.Reads = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryReadsByTxResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryReadsByTxResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_QueryReadsByTxResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.QueryReadsByTxResponse.reads": + if len(x.Reads) == 0 { + return protoreflect.ValueOfList(&_QueryReadsByTxResponse_1_list{}) + } + listValue := &_QueryReadsByTxResponse_1_list{list: &x.Reads} + return protoreflect.ValueOfList(listValue) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryReadsByTxResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryReadsByTxResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryReadsByTxResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.QueryReadsByTxResponse.reads": + lv := value.List() + clv := lv.(*_QueryReadsByTxResponse_1_list) + x.Reads = *clv.list + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryReadsByTxResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryReadsByTxResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryReadsByTxResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryReadsByTxResponse.reads": + if x.Reads == nil { + x.Reads = []*UniversalRead{} + } + value := &_QueryReadsByTxResponse_1_list{list: &x.Reads} + return protoreflect.ValueOfList(value) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryReadsByTxResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryReadsByTxResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_QueryReadsByTxResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.QueryReadsByTxResponse.reads": + list := []*UniversalRead{} + return protoreflect.ValueOfList(&_QueryReadsByTxResponse_1_list{list: &list}) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.QueryReadsByTxResponse")) + } + panic(fmt.Errorf("message ucallback.v1.QueryReadsByTxResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_QueryReadsByTxResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.QueryReadsByTxResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_QueryReadsByTxResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_QueryReadsByTxResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_QueryReadsByTxResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_QueryReadsByTxResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryReadsByTxResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if len(x.Reads) > 0 { + for _, e := range x.Reads { + l = options.Size(e) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*QueryReadsByTxResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Reads) > 0 { + for iNdEx := len(x.Reads) - 1; iNdEx >= 0; iNdEx-- { + encoded, err := options.Marshal(x.Reads[iNdEx]) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*QueryReadsByTxResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryReadsByTxResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryReadsByTxResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Reads", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Reads = append(x.Reads, &UniversalRead{}) + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Reads[len(x.Reads)-1]); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: ucallback/v1/query.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// QueryParamsRequest is the request type for the Query/Params RPC method. +type QueryParamsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *QueryParamsRequest) Reset() { + *x = QueryParamsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_query_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryParamsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryParamsRequest) ProtoMessage() {} + +// Deprecated: Use QueryParamsRequest.ProtoReflect.Descriptor instead. +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return file_ucallback_v1_query_proto_rawDescGZIP(), []int{0} +} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +type QueryParamsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // params defines the parameters of the module. + Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` +} + +func (x *QueryParamsResponse) Reset() { + *x = QueryParamsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_query_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryParamsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryParamsResponse) ProtoMessage() {} + +// Deprecated: Use QueryParamsResponse.ProtoReflect.Descriptor instead. +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return file_ucallback_v1_query_proto_rawDescGZIP(), []int{1} +} + +func (x *QueryParamsResponse) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +type QueryAllPendingReadRequestsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Pagination *v1beta1.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (x *QueryAllPendingReadRequestsRequest) Reset() { + *x = QueryAllPendingReadRequestsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_query_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryAllPendingReadRequestsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryAllPendingReadRequestsRequest) ProtoMessage() {} + +// Deprecated: Use QueryAllPendingReadRequestsRequest.ProtoReflect.Descriptor instead. +func (*QueryAllPendingReadRequestsRequest) Descriptor() ([]byte, []int) { + return file_ucallback_v1_query_proto_rawDescGZIP(), []int{2} +} + +func (x *QueryAllPendingReadRequestsRequest) GetPagination() *v1beta1.PageRequest { + if x != nil { + return x.Pagination + } + return nil +} + +type QueryAllPendingReadRequestsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Reads that are unsettled AND not yet past their expiry height. Requests past + // expiry are withheld here even before the sweeper retires them, so validators + // never take on work that can no longer be fulfilled in time. + Reads []*UniversalRead `protobuf:"bytes,1,rep,name=reads,proto3" json:"reads,omitempty"` + Pagination *v1beta1.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (x *QueryAllPendingReadRequestsResponse) Reset() { + *x = QueryAllPendingReadRequestsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_query_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryAllPendingReadRequestsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryAllPendingReadRequestsResponse) ProtoMessage() {} + +// Deprecated: Use QueryAllPendingReadRequestsResponse.ProtoReflect.Descriptor instead. +func (*QueryAllPendingReadRequestsResponse) Descriptor() ([]byte, []int) { + return file_ucallback_v1_query_proto_rawDescGZIP(), []int{3} +} + +func (x *QueryAllPendingReadRequestsResponse) GetReads() []*UniversalRead { + if x != nil { + return x.Reads + } + return nil +} + +func (x *QueryAllPendingReadRequestsResponse) GetPagination() *v1beta1.PageResponse { + if x != nil { + return x.Pagination + } + return nil +} + +type QueryUniversalReadRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` +} + +func (x *QueryUniversalReadRequest) Reset() { + *x = QueryUniversalReadRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_query_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryUniversalReadRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryUniversalReadRequest) ProtoMessage() {} + +// Deprecated: Use QueryUniversalReadRequest.ProtoReflect.Descriptor instead. +func (*QueryUniversalReadRequest) Descriptor() ([]byte, []int) { + return file_ucallback_v1_query_proto_rawDescGZIP(), []int{4} +} + +func (x *QueryUniversalReadRequest) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +type QueryUniversalReadResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Read *UniversalRead `protobuf:"bytes,1,opt,name=read,proto3" json:"read,omitempty"` +} + +func (x *QueryUniversalReadResponse) Reset() { + *x = QueryUniversalReadResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_query_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryUniversalReadResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryUniversalReadResponse) ProtoMessage() {} + +// Deprecated: Use QueryUniversalReadResponse.ProtoReflect.Descriptor instead. +func (*QueryUniversalReadResponse) Descriptor() ([]byte, []int) { + return file_ucallback_v1_query_proto_rawDescGZIP(), []int{5} +} + +func (x *QueryUniversalReadResponse) GetRead() *UniversalRead { + if x != nil { + return x.Read + } + return nil +} + +type QueryReadsByTxRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TxHash string `protobuf:"bytes,1,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"` +} + +func (x *QueryReadsByTxRequest) Reset() { + *x = QueryReadsByTxRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_query_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryReadsByTxRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryReadsByTxRequest) ProtoMessage() {} + +// Deprecated: Use QueryReadsByTxRequest.ProtoReflect.Descriptor instead. +func (*QueryReadsByTxRequest) Descriptor() ([]byte, []int) { + return file_ucallback_v1_query_proto_rawDescGZIP(), []int{6} +} + +func (x *QueryReadsByTxRequest) GetTxHash() string { + if x != nil { + return x.TxHash + } + return "" +} + +type QueryReadsByTxResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Every read the transaction requested, settled or not, in request-id order. + Reads []*UniversalRead `protobuf:"bytes,1,rep,name=reads,proto3" json:"reads,omitempty"` +} + +func (x *QueryReadsByTxResponse) Reset() { + *x = QueryReadsByTxResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_query_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryReadsByTxResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryReadsByTxResponse) ProtoMessage() {} + +// Deprecated: Use QueryReadsByTxResponse.ProtoReflect.Descriptor instead. +func (*QueryReadsByTxResponse) Descriptor() ([]byte, []int) { + return file_ucallback_v1_query_proto_rawDescGZIP(), []int{7} +} + +func (x *QueryReadsByTxResponse) GetReads() []*UniversalRead { + if x != nil { + return x.Reads + } + return nil +} + +var File_ucallback_v1_query_proto protoreflect.FileDescriptor + +var file_ucallback_v1_query_proto_rawDesc = []byte{ + 0x0a, 0x18, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x75, 0x63, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x18, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, + 0x76, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x14, + 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x43, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x06, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x75, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x6c, 0x0a, 0x22, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x41, 0x6c, 0x6c, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x46, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa7, 0x01, 0x0a, 0x23, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x41, 0x6c, 0x6c, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x37, 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, + 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x42, 0x04, 0xc8, 0xde, 0x1f, + 0x00, 0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x73, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x3a, 0x0a, 0x19, 0x51, 0x75, 0x65, 0x72, 0x79, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, + 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x22, 0x53, 0x0a, + 0x1a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x52, + 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x72, + 0x65, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x75, 0x63, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x04, 0x72, 0x65, + 0x61, 0x64, 0x22, 0x30, 0x0a, 0x15, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x73, + 0x42, 0x79, 0x54, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x74, + 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, + 0x48, 0x61, 0x73, 0x68, 0x22, 0x51, 0x0a, 0x16, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x61, + 0x64, 0x73, 0x42, 0x79, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, + 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, + 0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x73, 0x32, 0xc0, 0x04, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x12, 0x6b, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x20, 0x2e, 0x75, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, + 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x75, 0x63, 0x61, 0x6c, 0x6c, + 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0xaa, + 0x01, 0x0a, 0x16, 0x41, 0x6c, 0x6c, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x75, 0x63, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x41, 0x6c, + 0x6c, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x75, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x41, 0x6c, 0x6c, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x12, 0x23, 0x2f, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, + 0x63, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, + 0x61, 0x64, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x96, 0x01, 0x0a, 0x0d, + 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x12, 0x27, 0x2e, + 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, + 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x55, 0x6e, 0x69, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x12, 0x2a, 0x2f, 0x75, 0x63, 0x61, 0x6c, 0x6c, + 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, + 0x6c, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x73, 0x2f, 0x7b, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x83, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x61, 0x64, 0x73, 0x42, 0x79, + 0x54, 0x78, 0x12, 0x23, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, + 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, 0x73, 0x42, 0x79, 0x54, 0x78, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x61, 0x64, + 0x73, 0x42, 0x79, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x12, 0x23, 0x2f, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, + 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x61, 0x64, 0x73, 0x5f, 0x62, 0x79, 0x5f, 0x74, 0x78, + 0x2f, 0x7b, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x7d, 0x42, 0xb2, 0x01, 0x0a, 0x10, 0x63, + 0x6f, 0x6d, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x42, + 0x0a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x75, 0x73, 0x68, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x2f, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2d, 0x6e, + 0x6f, 0x64, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, + 0x6b, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x76, 0x31, + 0xa2, 0x02, 0x03, 0x55, 0x58, 0x58, 0xaa, 0x02, 0x0c, 0x55, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, + 0x63, 0x6b, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0c, 0x55, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, + 0x6b, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x18, 0x55, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, + 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x0d, 0x55, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x3a, 0x3a, 0x56, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_ucallback_v1_query_proto_rawDescOnce sync.Once + file_ucallback_v1_query_proto_rawDescData = file_ucallback_v1_query_proto_rawDesc +) + +func file_ucallback_v1_query_proto_rawDescGZIP() []byte { + file_ucallback_v1_query_proto_rawDescOnce.Do(func() { + file_ucallback_v1_query_proto_rawDescData = protoimpl.X.CompressGZIP(file_ucallback_v1_query_proto_rawDescData) + }) + return file_ucallback_v1_query_proto_rawDescData +} + +var file_ucallback_v1_query_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_ucallback_v1_query_proto_goTypes = []interface{}{ + (*QueryParamsRequest)(nil), // 0: ucallback.v1.QueryParamsRequest + (*QueryParamsResponse)(nil), // 1: ucallback.v1.QueryParamsResponse + (*QueryAllPendingReadRequestsRequest)(nil), // 2: ucallback.v1.QueryAllPendingReadRequestsRequest + (*QueryAllPendingReadRequestsResponse)(nil), // 3: ucallback.v1.QueryAllPendingReadRequestsResponse + (*QueryUniversalReadRequest)(nil), // 4: ucallback.v1.QueryUniversalReadRequest + (*QueryUniversalReadResponse)(nil), // 5: ucallback.v1.QueryUniversalReadResponse + (*QueryReadsByTxRequest)(nil), // 6: ucallback.v1.QueryReadsByTxRequest + (*QueryReadsByTxResponse)(nil), // 7: ucallback.v1.QueryReadsByTxResponse + (*Params)(nil), // 8: ucallback.v1.Params + (*v1beta1.PageRequest)(nil), // 9: cosmos.base.query.v1beta1.PageRequest + (*UniversalRead)(nil), // 10: ucallback.v1.UniversalRead + (*v1beta1.PageResponse)(nil), // 11: cosmos.base.query.v1beta1.PageResponse +} +var file_ucallback_v1_query_proto_depIdxs = []int32{ + 8, // 0: ucallback.v1.QueryParamsResponse.params:type_name -> ucallback.v1.Params + 9, // 1: ucallback.v1.QueryAllPendingReadRequestsRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 10, // 2: ucallback.v1.QueryAllPendingReadRequestsResponse.reads:type_name -> ucallback.v1.UniversalRead + 11, // 3: ucallback.v1.QueryAllPendingReadRequestsResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 10, // 4: ucallback.v1.QueryUniversalReadResponse.read:type_name -> ucallback.v1.UniversalRead + 10, // 5: ucallback.v1.QueryReadsByTxResponse.reads:type_name -> ucallback.v1.UniversalRead + 0, // 6: ucallback.v1.Query.Params:input_type -> ucallback.v1.QueryParamsRequest + 2, // 7: ucallback.v1.Query.AllPendingReadRequests:input_type -> ucallback.v1.QueryAllPendingReadRequestsRequest + 4, // 8: ucallback.v1.Query.UniversalRead:input_type -> ucallback.v1.QueryUniversalReadRequest + 6, // 9: ucallback.v1.Query.ReadsByTx:input_type -> ucallback.v1.QueryReadsByTxRequest + 1, // 10: ucallback.v1.Query.Params:output_type -> ucallback.v1.QueryParamsResponse + 3, // 11: ucallback.v1.Query.AllPendingReadRequests:output_type -> ucallback.v1.QueryAllPendingReadRequestsResponse + 5, // 12: ucallback.v1.Query.UniversalRead:output_type -> ucallback.v1.QueryUniversalReadResponse + 7, // 13: ucallback.v1.Query.ReadsByTx:output_type -> ucallback.v1.QueryReadsByTxResponse + 10, // [10:14] is the sub-list for method output_type + 6, // [6:10] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name +} + +func init() { file_ucallback_v1_query_proto_init() } +func file_ucallback_v1_query_proto_init() { + if File_ucallback_v1_query_proto != nil { + return + } + file_ucallback_v1_genesis_proto_init() + file_ucallback_v1_types_proto_init() + if !protoimpl.UnsafeEnabled { + file_ucallback_v1_query_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryParamsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_query_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryParamsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_query_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryAllPendingReadRequestsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_query_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryAllPendingReadRequestsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_query_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryUniversalReadRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_query_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryUniversalReadResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_query_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryReadsByTxRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_query_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryReadsByTxResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_ucallback_v1_query_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_ucallback_v1_query_proto_goTypes, + DependencyIndexes: file_ucallback_v1_query_proto_depIdxs, + MessageInfos: file_ucallback_v1_query_proto_msgTypes, + }.Build() + File_ucallback_v1_query_proto = out.File + file_ucallback_v1_query_proto_rawDesc = nil + file_ucallback_v1_query_proto_goTypes = nil + file_ucallback_v1_query_proto_depIdxs = nil +} diff --git a/api/ucallback/v1/query_grpc.pb.go b/api/ucallback/v1/query_grpc.pb.go new file mode 100644 index 00000000..20db2bc9 --- /dev/null +++ b/api/ucallback/v1/query_grpc.pb.go @@ -0,0 +1,232 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: ucallback/v1/query.proto + +package ucallbackv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + Query_Params_FullMethodName = "/ucallback.v1.Query/Params" + Query_AllPendingReadRequests_FullMethodName = "/ucallback.v1.Query/AllPendingReadRequests" + Query_UniversalRead_FullMethodName = "/ucallback.v1.Query/UniversalRead" + Query_ReadsByTx_FullMethodName = "/ucallback.v1.Query/ReadsByTx" +) + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type QueryClient interface { + // Params queries all parameters of the module. + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // AllPendingReadRequests lists read requests still awaiting an observation. + // This is the endpoint universal validators poll. + AllPendingReadRequests(ctx context.Context, in *QueryAllPendingReadRequestsRequest, opts ...grpc.CallOption) (*QueryAllPendingReadRequestsResponse, error) + // UniversalRead returns one read by request id, at any point in its lifecycle. + UniversalRead(ctx context.Context, in *QueryUniversalReadRequest, opts ...grpc.CallOption) (*QueryUniversalReadResponse, error) + // ReadsByTxHash returns every read requested by one Push transaction. A single + // transaction can emit several ReadRequested logs; this reassembles that batch. + ReadsByTx(ctx context.Context, in *QueryReadsByTxRequest, opts ...grpc.CallOption) (*QueryReadsByTxResponse, error) +} + +type queryClient struct { + cc grpc.ClientConnInterface +} + +func NewQueryClient(cc grpc.ClientConnInterface) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, Query_Params_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) AllPendingReadRequests(ctx context.Context, in *QueryAllPendingReadRequestsRequest, opts ...grpc.CallOption) (*QueryAllPendingReadRequestsResponse, error) { + out := new(QueryAllPendingReadRequestsResponse) + err := c.cc.Invoke(ctx, Query_AllPendingReadRequests_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) UniversalRead(ctx context.Context, in *QueryUniversalReadRequest, opts ...grpc.CallOption) (*QueryUniversalReadResponse, error) { + out := new(QueryUniversalReadResponse) + err := c.cc.Invoke(ctx, Query_UniversalRead_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) ReadsByTx(ctx context.Context, in *QueryReadsByTxRequest, opts ...grpc.CallOption) (*QueryReadsByTxResponse, error) { + out := new(QueryReadsByTxResponse) + err := c.cc.Invoke(ctx, Query_ReadsByTx_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +// All implementations must embed UnimplementedQueryServer +// for forward compatibility +type QueryServer interface { + // Params queries all parameters of the module. + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // AllPendingReadRequests lists read requests still awaiting an observation. + // This is the endpoint universal validators poll. + AllPendingReadRequests(context.Context, *QueryAllPendingReadRequestsRequest) (*QueryAllPendingReadRequestsResponse, error) + // UniversalRead returns one read by request id, at any point in its lifecycle. + UniversalRead(context.Context, *QueryUniversalReadRequest) (*QueryUniversalReadResponse, error) + // ReadsByTxHash returns every read requested by one Push transaction. A single + // transaction can emit several ReadRequested logs; this reassembles that batch. + ReadsByTx(context.Context, *QueryReadsByTxRequest) (*QueryReadsByTxResponse, error) + mustEmbedUnimplementedQueryServer() +} + +// UnimplementedQueryServer must be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (UnimplementedQueryServer) Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} +func (UnimplementedQueryServer) AllPendingReadRequests(context.Context, *QueryAllPendingReadRequestsRequest) (*QueryAllPendingReadRequestsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AllPendingReadRequests not implemented") +} +func (UnimplementedQueryServer) UniversalRead(context.Context, *QueryUniversalReadRequest) (*QueryUniversalReadResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UniversalRead not implemented") +} +func (UnimplementedQueryServer) ReadsByTx(context.Context, *QueryReadsByTxRequest) (*QueryReadsByTxResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReadsByTx not implemented") +} +func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {} + +// UnsafeQueryServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to QueryServer will +// result in compilation errors. +type UnsafeQueryServer interface { + mustEmbedUnimplementedQueryServer() +} + +func RegisterQueryServer(s grpc.ServiceRegistrar, srv QueryServer) { + s.RegisterService(&Query_ServiceDesc, srv) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Query_Params_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_AllPendingReadRequests_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAllPendingReadRequestsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).AllPendingReadRequests(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Query_AllPendingReadRequests_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).AllPendingReadRequests(ctx, req.(*QueryAllPendingReadRequestsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_UniversalRead_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryUniversalReadRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).UniversalRead(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Query_UniversalRead_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).UniversalRead(ctx, req.(*QueryUniversalReadRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_ReadsByTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryReadsByTxRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ReadsByTx(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Query_ReadsByTx_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ReadsByTx(ctx, req.(*QueryReadsByTxRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Query_ServiceDesc is the grpc.ServiceDesc for Query service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Query_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "ucallback.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + { + MethodName: "AllPendingReadRequests", + Handler: _Query_AllPendingReadRequests_Handler, + }, + { + MethodName: "UniversalRead", + Handler: _Query_UniversalRead_Handler, + }, + { + MethodName: "ReadsByTx", + Handler: _Query_ReadsByTx_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ucallback/v1/query.proto", +} diff --git a/api/ucallback/v1/tx.pulsar.go b/api/ucallback/v1/tx.pulsar.go new file mode 100644 index 00000000..321b1fa9 --- /dev/null +++ b/api/ucallback/v1/tx.pulsar.go @@ -0,0 +1,2215 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package ucallbackv1 + +import ( + _ "cosmossdk.io/api/amino" + _ "cosmossdk.io/api/cosmos/msg/v1" + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "github.com/cosmos/gogoproto/gogoproto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_MsgUpdateParams protoreflect.MessageDescriptor + fd_MsgUpdateParams_authority protoreflect.FieldDescriptor + fd_MsgUpdateParams_params protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_tx_proto_init() + md_MsgUpdateParams = File_ucallback_v1_tx_proto.Messages().ByName("MsgUpdateParams") + fd_MsgUpdateParams_authority = md_MsgUpdateParams.Fields().ByName("authority") + fd_MsgUpdateParams_params = md_MsgUpdateParams.Fields().ByName("params") +} + +var _ protoreflect.Message = (*fastReflection_MsgUpdateParams)(nil) + +type fastReflection_MsgUpdateParams MsgUpdateParams + +func (x *MsgUpdateParams) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgUpdateParams)(x) +} + +func (x *MsgUpdateParams) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_tx_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgUpdateParams_messageType fastReflection_MsgUpdateParams_messageType +var _ protoreflect.MessageType = fastReflection_MsgUpdateParams_messageType{} + +type fastReflection_MsgUpdateParams_messageType struct{} + +func (x fastReflection_MsgUpdateParams_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgUpdateParams)(nil) +} +func (x fastReflection_MsgUpdateParams_messageType) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParams) +} +func (x fastReflection_MsgUpdateParams_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParams +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgUpdateParams) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParams +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgUpdateParams) Type() protoreflect.MessageType { + return _fastReflection_MsgUpdateParams_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgUpdateParams) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParams) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgUpdateParams) Interface() protoreflect.ProtoMessage { + return (*MsgUpdateParams)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgUpdateParams) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Authority != "" { + value := protoreflect.ValueOfString(x.Authority) + if !f(fd_MsgUpdateParams_authority, value) { + return + } + } + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_MsgUpdateParams_params, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgUpdateParams) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.MsgUpdateParams.authority": + return x.Authority != "" + case "ucallback.v1.MsgUpdateParams.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message ucallback.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParams) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.MsgUpdateParams.authority": + x.Authority = "" + case "ucallback.v1.MsgUpdateParams.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message ucallback.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgUpdateParams) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.MsgUpdateParams.authority": + value := x.Authority + return protoreflect.ValueOfString(value) + case "ucallback.v1.MsgUpdateParams.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message ucallback.v1.MsgUpdateParams does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParams) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.MsgUpdateParams.authority": + x.Authority = value.Interface().(string) + case "ucallback.v1.MsgUpdateParams.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message ucallback.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParams) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.MsgUpdateParams.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + case "ucallback.v1.MsgUpdateParams.authority": + panic(fmt.Errorf("field authority of message ucallback.v1.MsgUpdateParams is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message ucallback.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgUpdateParams) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.MsgUpdateParams.authority": + return protoreflect.ValueOfString("") + case "ucallback.v1.MsgUpdateParams.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message ucallback.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgUpdateParams) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.MsgUpdateParams", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgUpdateParams) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParams) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgUpdateParams) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgUpdateParams) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgUpdateParams) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Authority) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgUpdateParams) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if len(x.Authority) > 0 { + i -= len(x.Authority) + copy(dAtA[i:], x.Authority) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authority))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgUpdateParams) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_MsgUpdateParamsResponse protoreflect.MessageDescriptor +) + +func init() { + file_ucallback_v1_tx_proto_init() + md_MsgUpdateParamsResponse = File_ucallback_v1_tx_proto.Messages().ByName("MsgUpdateParamsResponse") +} + +var _ protoreflect.Message = (*fastReflection_MsgUpdateParamsResponse)(nil) + +type fastReflection_MsgUpdateParamsResponse MsgUpdateParamsResponse + +func (x *MsgUpdateParamsResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgUpdateParamsResponse)(x) +} + +func (x *MsgUpdateParamsResponse) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_tx_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgUpdateParamsResponse_messageType fastReflection_MsgUpdateParamsResponse_messageType +var _ protoreflect.MessageType = fastReflection_MsgUpdateParamsResponse_messageType{} + +type fastReflection_MsgUpdateParamsResponse_messageType struct{} + +func (x fastReflection_MsgUpdateParamsResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgUpdateParamsResponse)(nil) +} +func (x fastReflection_MsgUpdateParamsResponse_messageType) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParamsResponse) +} +func (x fastReflection_MsgUpdateParamsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParamsResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgUpdateParamsResponse) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParamsResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgUpdateParamsResponse) Type() protoreflect.MessageType { + return _fastReflection_MsgUpdateParamsResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgUpdateParamsResponse) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParamsResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgUpdateParamsResponse) Interface() protoreflect.ProtoMessage { + return (*MsgUpdateParamsResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgUpdateParamsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgUpdateParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParamsResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgUpdateParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.MsgUpdateParamsResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParamsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgUpdateParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message ucallback.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgUpdateParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.MsgUpdateParamsResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgUpdateParamsResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgUpdateParamsResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgUpdateParamsResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgUpdateParamsResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgUpdateParamsResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgUpdateParamsResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgUpdateParamsResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_MsgVoteReadResult protoreflect.MessageDescriptor + fd_MsgVoteReadResult_signer protoreflect.FieldDescriptor + fd_MsgVoteReadResult_request_id protoreflect.FieldDescriptor + fd_MsgVoteReadResult_result protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_tx_proto_init() + md_MsgVoteReadResult = File_ucallback_v1_tx_proto.Messages().ByName("MsgVoteReadResult") + fd_MsgVoteReadResult_signer = md_MsgVoteReadResult.Fields().ByName("signer") + fd_MsgVoteReadResult_request_id = md_MsgVoteReadResult.Fields().ByName("request_id") + fd_MsgVoteReadResult_result = md_MsgVoteReadResult.Fields().ByName("result") +} + +var _ protoreflect.Message = (*fastReflection_MsgVoteReadResult)(nil) + +type fastReflection_MsgVoteReadResult MsgVoteReadResult + +func (x *MsgVoteReadResult) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgVoteReadResult)(x) +} + +func (x *MsgVoteReadResult) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_tx_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgVoteReadResult_messageType fastReflection_MsgVoteReadResult_messageType +var _ protoreflect.MessageType = fastReflection_MsgVoteReadResult_messageType{} + +type fastReflection_MsgVoteReadResult_messageType struct{} + +func (x fastReflection_MsgVoteReadResult_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgVoteReadResult)(nil) +} +func (x fastReflection_MsgVoteReadResult_messageType) New() protoreflect.Message { + return new(fastReflection_MsgVoteReadResult) +} +func (x fastReflection_MsgVoteReadResult_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgVoteReadResult +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgVoteReadResult) Descriptor() protoreflect.MessageDescriptor { + return md_MsgVoteReadResult +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgVoteReadResult) Type() protoreflect.MessageType { + return _fastReflection_MsgVoteReadResult_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgVoteReadResult) New() protoreflect.Message { + return new(fastReflection_MsgVoteReadResult) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgVoteReadResult) Interface() protoreflect.ProtoMessage { + return (*MsgVoteReadResult)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgVoteReadResult) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Signer != "" { + value := protoreflect.ValueOfString(x.Signer) + if !f(fd_MsgVoteReadResult_signer, value) { + return + } + } + if x.RequestId != "" { + value := protoreflect.ValueOfString(x.RequestId) + if !f(fd_MsgVoteReadResult_request_id, value) { + return + } + } + if x.Result != nil { + value := protoreflect.ValueOfMessage(x.Result.ProtoReflect()) + if !f(fd_MsgVoteReadResult_result, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgVoteReadResult) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.MsgVoteReadResult.signer": + return x.Signer != "" + case "ucallback.v1.MsgVoteReadResult.request_id": + return x.RequestId != "" + case "ucallback.v1.MsgVoteReadResult.result": + return x.Result != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgVoteReadResult")) + } + panic(fmt.Errorf("message ucallback.v1.MsgVoteReadResult does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgVoteReadResult) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.MsgVoteReadResult.signer": + x.Signer = "" + case "ucallback.v1.MsgVoteReadResult.request_id": + x.RequestId = "" + case "ucallback.v1.MsgVoteReadResult.result": + x.Result = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgVoteReadResult")) + } + panic(fmt.Errorf("message ucallback.v1.MsgVoteReadResult does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgVoteReadResult) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.MsgVoteReadResult.signer": + value := x.Signer + return protoreflect.ValueOfString(value) + case "ucallback.v1.MsgVoteReadResult.request_id": + value := x.RequestId + return protoreflect.ValueOfString(value) + case "ucallback.v1.MsgVoteReadResult.result": + value := x.Result + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgVoteReadResult")) + } + panic(fmt.Errorf("message ucallback.v1.MsgVoteReadResult does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgVoteReadResult) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.MsgVoteReadResult.signer": + x.Signer = value.Interface().(string) + case "ucallback.v1.MsgVoteReadResult.request_id": + x.RequestId = value.Interface().(string) + case "ucallback.v1.MsgVoteReadResult.result": + x.Result = value.Message().Interface().(*ReadResult) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgVoteReadResult")) + } + panic(fmt.Errorf("message ucallback.v1.MsgVoteReadResult does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgVoteReadResult) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.MsgVoteReadResult.result": + if x.Result == nil { + x.Result = new(ReadResult) + } + return protoreflect.ValueOfMessage(x.Result.ProtoReflect()) + case "ucallback.v1.MsgVoteReadResult.signer": + panic(fmt.Errorf("field signer of message ucallback.v1.MsgVoteReadResult is not mutable")) + case "ucallback.v1.MsgVoteReadResult.request_id": + panic(fmt.Errorf("field request_id of message ucallback.v1.MsgVoteReadResult is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgVoteReadResult")) + } + panic(fmt.Errorf("message ucallback.v1.MsgVoteReadResult does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgVoteReadResult) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.MsgVoteReadResult.signer": + return protoreflect.ValueOfString("") + case "ucallback.v1.MsgVoteReadResult.request_id": + return protoreflect.ValueOfString("") + case "ucallback.v1.MsgVoteReadResult.result": + m := new(ReadResult) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgVoteReadResult")) + } + panic(fmt.Errorf("message ucallback.v1.MsgVoteReadResult does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgVoteReadResult) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.MsgVoteReadResult", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgVoteReadResult) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgVoteReadResult) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgVoteReadResult) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgVoteReadResult) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgVoteReadResult) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Signer) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.RequestId) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Result != nil { + l = options.Size(x.Result) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgVoteReadResult) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Result != nil { + encoded, err := options.Marshal(x.Result) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x1a + } + if len(x.RequestId) > 0 { + i -= len(x.RequestId) + copy(dAtA[i:], x.RequestId) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.RequestId))) + i-- + dAtA[i] = 0x12 + } + if len(x.Signer) > 0 { + i -= len(x.Signer) + copy(dAtA[i:], x.Signer) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Signer))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgVoteReadResult) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgVoteReadResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgVoteReadResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field RequestId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.RequestId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Result == nil { + x.Result = &ReadResult{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Result); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_MsgVoteReadResultResponse protoreflect.MessageDescriptor + fd_MsgVoteReadResultResponse_finalized protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_tx_proto_init() + md_MsgVoteReadResultResponse = File_ucallback_v1_tx_proto.Messages().ByName("MsgVoteReadResultResponse") + fd_MsgVoteReadResultResponse_finalized = md_MsgVoteReadResultResponse.Fields().ByName("finalized") +} + +var _ protoreflect.Message = (*fastReflection_MsgVoteReadResultResponse)(nil) + +type fastReflection_MsgVoteReadResultResponse MsgVoteReadResultResponse + +func (x *MsgVoteReadResultResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgVoteReadResultResponse)(x) +} + +func (x *MsgVoteReadResultResponse) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_tx_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_MsgVoteReadResultResponse_messageType fastReflection_MsgVoteReadResultResponse_messageType +var _ protoreflect.MessageType = fastReflection_MsgVoteReadResultResponse_messageType{} + +type fastReflection_MsgVoteReadResultResponse_messageType struct{} + +func (x fastReflection_MsgVoteReadResultResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgVoteReadResultResponse)(nil) +} +func (x fastReflection_MsgVoteReadResultResponse_messageType) New() protoreflect.Message { + return new(fastReflection_MsgVoteReadResultResponse) +} +func (x fastReflection_MsgVoteReadResultResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgVoteReadResultResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgVoteReadResultResponse) Descriptor() protoreflect.MessageDescriptor { + return md_MsgVoteReadResultResponse +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_MsgVoteReadResultResponse) Type() protoreflect.MessageType { + return _fastReflection_MsgVoteReadResultResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgVoteReadResultResponse) New() protoreflect.Message { + return new(fastReflection_MsgVoteReadResultResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgVoteReadResultResponse) Interface() protoreflect.ProtoMessage { + return (*MsgVoteReadResultResponse)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_MsgVoteReadResultResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Finalized != false { + value := protoreflect.ValueOfBool(x.Finalized) + if !f(fd_MsgVoteReadResultResponse_finalized, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_MsgVoteReadResultResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.MsgVoteReadResultResponse.finalized": + return x.Finalized != false + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgVoteReadResultResponse")) + } + panic(fmt.Errorf("message ucallback.v1.MsgVoteReadResultResponse does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgVoteReadResultResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.MsgVoteReadResultResponse.finalized": + x.Finalized = false + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgVoteReadResultResponse")) + } + panic(fmt.Errorf("message ucallback.v1.MsgVoteReadResultResponse does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_MsgVoteReadResultResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.MsgVoteReadResultResponse.finalized": + value := x.Finalized + return protoreflect.ValueOfBool(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgVoteReadResultResponse")) + } + panic(fmt.Errorf("message ucallback.v1.MsgVoteReadResultResponse does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgVoteReadResultResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.MsgVoteReadResultResponse.finalized": + x.Finalized = value.Bool() + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgVoteReadResultResponse")) + } + panic(fmt.Errorf("message ucallback.v1.MsgVoteReadResultResponse does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgVoteReadResultResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.MsgVoteReadResultResponse.finalized": + panic(fmt.Errorf("field finalized of message ucallback.v1.MsgVoteReadResultResponse is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgVoteReadResultResponse")) + } + panic(fmt.Errorf("message ucallback.v1.MsgVoteReadResultResponse does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_MsgVoteReadResultResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.MsgVoteReadResultResponse.finalized": + return protoreflect.ValueOfBool(false) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.MsgVoteReadResultResponse")) + } + panic(fmt.Errorf("message ucallback.v1.MsgVoteReadResultResponse does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_MsgVoteReadResultResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.MsgVoteReadResultResponse", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_MsgVoteReadResultResponse) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_MsgVoteReadResultResponse) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_MsgVoteReadResultResponse) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_MsgVoteReadResultResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgVoteReadResultResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Finalized { + n += 2 + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*MsgVoteReadResultResponse) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Finalized { + i-- + if x.Finalized { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*MsgVoteReadResultResponse) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgVoteReadResultResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgVoteReadResultResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Finalized", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + x.Finalized = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: ucallback/v1/tx.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// MsgUpdateParams is the Msg/UpdateParams request type. +// +// Since: cosmos-sdk 0.47 +type MsgUpdateParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // authority is the address of the governance account. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the parameters to update. + // + // NOTE: All parameters must be supplied. + Params *Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` +} + +func (x *MsgUpdateParams) Reset() { + *x = MsgUpdateParams{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_tx_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgUpdateParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgUpdateParams) ProtoMessage() {} + +// Deprecated: Use MsgUpdateParams.ProtoReflect.Descriptor instead. +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return file_ucallback_v1_tx_proto_rawDescGZIP(), []int{0} +} + +func (x *MsgUpdateParams) GetAuthority() string { + if x != nil { + return x.Authority + } + return "" +} + +func (x *MsgUpdateParams) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +// MsgUpdateParamsResponse defines the response structure for executing a +// MsgUpdateParams message. +// +// Since: cosmos-sdk 0.47 +type MsgUpdateParamsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *MsgUpdateParamsResponse) Reset() { + *x = MsgUpdateParamsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_tx_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgUpdateParamsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgUpdateParamsResponse) ProtoMessage() {} + +// Deprecated: Use MsgUpdateParamsResponse.ProtoReflect.Descriptor instead. +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return file_ucallback_v1_tx_proto_rawDescGZIP(), []int{1} +} + +// MsgVoteReadResult is broadcast by a universal validator that has executed a +// read request against the destination chain. +// +// The ballot the vote lands on is derived from (request_id, result), so two +// validators reporting the same observation converge on one ballot and any +// disagreement produces a distinct ballot that never reaches quorum. Nothing +// validator-local may appear in `result` for that reason — notably there is no +// error message field. +type MsgVoteReadResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // signer is the Cosmos address of the voting universal validator. + Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` + // request_id identifies the read request being voted on. + RequestId string `protobuf:"bytes,2,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + // result is the observation. Every field participates in the ballot key. + Result *ReadResult `protobuf:"bytes,3,opt,name=result,proto3" json:"result,omitempty"` +} + +func (x *MsgVoteReadResult) Reset() { + *x = MsgVoteReadResult{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_tx_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgVoteReadResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgVoteReadResult) ProtoMessage() {} + +// Deprecated: Use MsgVoteReadResult.ProtoReflect.Descriptor instead. +func (*MsgVoteReadResult) Descriptor() ([]byte, []int) { + return file_ucallback_v1_tx_proto_rawDescGZIP(), []int{2} +} + +func (x *MsgVoteReadResult) GetSigner() string { + if x != nil { + return x.Signer + } + return "" +} + +func (x *MsgVoteReadResult) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +func (x *MsgVoteReadResult) GetResult() *ReadResult { + if x != nil { + return x.Result + } + return nil +} + +type MsgVoteReadResultResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // finalized reports whether this vote carried the ballot to quorum. + Finalized bool `protobuf:"varint,1,opt,name=finalized,proto3" json:"finalized,omitempty"` +} + +func (x *MsgVoteReadResultResponse) Reset() { + *x = MsgVoteReadResultResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_tx_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgVoteReadResultResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgVoteReadResultResponse) ProtoMessage() {} + +// Deprecated: Use MsgVoteReadResultResponse.ProtoReflect.Descriptor instead. +func (*MsgVoteReadResultResponse) Descriptor() ([]byte, []int) { + return file_ucallback_v1_tx_proto_rawDescGZIP(), []int{3} +} + +func (x *MsgVoteReadResultResponse) GetFinalized() bool { + if x != nil { + return x.Finalized + } + return false +} + +var File_ucallback_v1_tx_proto protoreflect.FileDescriptor + +var file_ucallback_v1_tx_proto_rawDesc = []byte{ + 0x0a, 0x15, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x74, + 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, + 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x1a, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x73, + 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1a, + 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x67, 0x65, 0x6e, + 0x65, 0x73, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x18, 0x75, 0x63, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, + 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x01, 0x0a, 0x0f, 0x4d, 0x73, 0x67, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x36, 0x0a, 0x09, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x12, 0x32, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, + 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x0e, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0xc3, 0x01, 0x0a, 0x11, 0x4d, 0x73, 0x67, 0x56, 0x6f, 0x74, 0x65, 0x52, + 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x30, 0x0a, 0x06, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x75, 0x63, 0x61, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x3a, 0x2b, 0x82, 0xe7, + 0xb0, 0x2a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x8a, 0xe7, 0xb0, 0x2a, 0x1b, 0x75, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x4d, 0x73, 0x67, 0x56, 0x6f, 0x74, 0x65, 0x52, + 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x39, 0x0a, 0x19, 0x4d, 0x73, 0x67, + 0x56, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x66, 0x69, 0x6e, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x64, 0x32, 0xbe, 0x01, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x5a, 0x0a, 0x0e, + 0x56, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, + 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, + 0x67, 0x56, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x1a, + 0x27, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x73, 0x67, 0x56, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1d, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, + 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x25, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, + 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0xaf, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x75, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x70, 0x75, 0x73, 0x68, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x70, 0x75, 0x73, 0x68, + 0x2d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, + 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x63, 0x61, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x55, 0x58, 0x58, 0xaa, 0x02, + 0x0c, 0x55, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0c, + 0x55, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x18, 0x55, + 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0d, 0x55, 0x63, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_ucallback_v1_tx_proto_rawDescOnce sync.Once + file_ucallback_v1_tx_proto_rawDescData = file_ucallback_v1_tx_proto_rawDesc +) + +func file_ucallback_v1_tx_proto_rawDescGZIP() []byte { + file_ucallback_v1_tx_proto_rawDescOnce.Do(func() { + file_ucallback_v1_tx_proto_rawDescData = protoimpl.X.CompressGZIP(file_ucallback_v1_tx_proto_rawDescData) + }) + return file_ucallback_v1_tx_proto_rawDescData +} + +var file_ucallback_v1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_ucallback_v1_tx_proto_goTypes = []interface{}{ + (*MsgUpdateParams)(nil), // 0: ucallback.v1.MsgUpdateParams + (*MsgUpdateParamsResponse)(nil), // 1: ucallback.v1.MsgUpdateParamsResponse + (*MsgVoteReadResult)(nil), // 2: ucallback.v1.MsgVoteReadResult + (*MsgVoteReadResultResponse)(nil), // 3: ucallback.v1.MsgVoteReadResultResponse + (*Params)(nil), // 4: ucallback.v1.Params + (*ReadResult)(nil), // 5: ucallback.v1.ReadResult +} +var file_ucallback_v1_tx_proto_depIdxs = []int32{ + 4, // 0: ucallback.v1.MsgUpdateParams.params:type_name -> ucallback.v1.Params + 5, // 1: ucallback.v1.MsgVoteReadResult.result:type_name -> ucallback.v1.ReadResult + 2, // 2: ucallback.v1.Msg.VoteReadResult:input_type -> ucallback.v1.MsgVoteReadResult + 0, // 3: ucallback.v1.Msg.UpdateParams:input_type -> ucallback.v1.MsgUpdateParams + 3, // 4: ucallback.v1.Msg.VoteReadResult:output_type -> ucallback.v1.MsgVoteReadResultResponse + 1, // 5: ucallback.v1.Msg.UpdateParams:output_type -> ucallback.v1.MsgUpdateParamsResponse + 4, // [4:6] is the sub-list for method output_type + 2, // [2:4] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_ucallback_v1_tx_proto_init() } +func file_ucallback_v1_tx_proto_init() { + if File_ucallback_v1_tx_proto != nil { + return + } + file_ucallback_v1_genesis_proto_init() + file_ucallback_v1_types_proto_init() + if !protoimpl.UnsafeEnabled { + file_ucallback_v1_tx_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgUpdateParams); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_tx_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgUpdateParamsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_tx_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgVoteReadResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_tx_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgVoteReadResultResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_ucallback_v1_tx_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_ucallback_v1_tx_proto_goTypes, + DependencyIndexes: file_ucallback_v1_tx_proto_depIdxs, + MessageInfos: file_ucallback_v1_tx_proto_msgTypes, + }.Build() + File_ucallback_v1_tx_proto = out.File + file_ucallback_v1_tx_proto_rawDesc = nil + file_ucallback_v1_tx_proto_goTypes = nil + file_ucallback_v1_tx_proto_depIdxs = nil +} diff --git a/api/ucallback/v1/tx_grpc.pb.go b/api/ucallback/v1/tx_grpc.pb.go new file mode 100644 index 00000000..ed533eb9 --- /dev/null +++ b/api/ucallback/v1/tx_grpc.pb.go @@ -0,0 +1,156 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: ucallback/v1/tx.proto + +package ucallbackv1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + Msg_VoteReadResult_FullMethodName = "/ucallback.v1.Msg/VoteReadResult" + Msg_UpdateParams_FullMethodName = "/ucallback.v1.Msg/UpdateParams" +) + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type MsgClient interface { + // VoteReadResult submits one universal validator's observation of a read + // request's outcome on the destination chain. + VoteReadResult(ctx context.Context, in *MsgVoteReadResult, opts ...grpc.CallOption) (*MsgVoteReadResultResponse, error) + // UpdateParams defines a governance operation for updating the parameters. + // + // Since: cosmos-sdk 0.47 + UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) +} + +type msgClient struct { + cc grpc.ClientConnInterface +} + +func NewMsgClient(cc grpc.ClientConnInterface) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) VoteReadResult(ctx context.Context, in *MsgVoteReadResult, opts ...grpc.CallOption) (*MsgVoteReadResultResponse, error) { + out := new(MsgVoteReadResultResponse) + err := c.cc.Invoke(ctx, Msg_VoteReadResult_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, Msg_UpdateParams_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +// All implementations must embed UnimplementedMsgServer +// for forward compatibility +type MsgServer interface { + // VoteReadResult submits one universal validator's observation of a read + // request's outcome on the destination chain. + VoteReadResult(context.Context, *MsgVoteReadResult) (*MsgVoteReadResultResponse, error) + // UpdateParams defines a governance operation for updating the parameters. + // + // Since: cosmos-sdk 0.47 + UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) + mustEmbedUnimplementedMsgServer() +} + +// UnimplementedMsgServer must be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (UnimplementedMsgServer) VoteReadResult(context.Context, *MsgVoteReadResult) (*MsgVoteReadResultResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method VoteReadResult not implemented") +} +func (UnimplementedMsgServer) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") +} +func (UnimplementedMsgServer) mustEmbedUnimplementedMsgServer() {} + +// UnsafeMsgServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to MsgServer will +// result in compilation errors. +type UnsafeMsgServer interface { + mustEmbedUnimplementedMsgServer() +} + +func RegisterMsgServer(s grpc.ServiceRegistrar, srv MsgServer) { + s.RegisterService(&Msg_ServiceDesc, srv) +} + +func _Msg_VoteReadResult_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgVoteReadResult) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).VoteReadResult(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Msg_VoteReadResult_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).VoteReadResult(ctx, req.(*MsgVoteReadResult)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Msg_UpdateParams_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) +} + +// Msg_ServiceDesc is the grpc.ServiceDesc for Msg service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Msg_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "ucallback.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "VoteReadResult", + Handler: _Msg_VoteReadResult_Handler, + }, + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ucallback/v1/tx.proto", +} diff --git a/api/ucallback/v1/types.pulsar.go b/api/ucallback/v1/types.pulsar.go new file mode 100644 index 00000000..f53b9d4d --- /dev/null +++ b/api/ucallback/v1/types.pulsar.go @@ -0,0 +1,3992 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package ucallbackv1 + +import ( + _ "cosmossdk.io/api/amino" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "github.com/cosmos/gogoproto/gogoproto" + v1 "github.com/pushchain/push-chain-node/api/uexecutor/v1" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_ReadRequest protoreflect.MessageDescriptor + fd_ReadRequest_request_id protoreflect.FieldDescriptor + fd_ReadRequest_destination_chain protoreflect.FieldDescriptor + fd_ReadRequest_owner protoreflect.FieldDescriptor + fd_ReadRequest_query protoreflect.FieldDescriptor + fd_ReadRequest_min_confirmations protoreflect.FieldDescriptor + fd_ReadRequest_destination_block_height protoreflect.FieldDescriptor + fd_ReadRequest_expiry_block_height protoreflect.FieldDescriptor + fd_ReadRequest_created_at_height protoreflect.FieldDescriptor + fd_ReadRequest_callback_target protoreflect.FieldDescriptor + fd_ReadRequest_original_funder protoreflect.FieldDescriptor + fd_ReadRequest_fees_deposited protoreflect.FieldDescriptor + fd_ReadRequest_max_fee protoreflect.FieldDescriptor + fd_ReadRequest_requested_tx_hash protoreflect.FieldDescriptor + fd_ReadRequest_requested_log_index protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_types_proto_init() + md_ReadRequest = File_ucallback_v1_types_proto.Messages().ByName("ReadRequest") + fd_ReadRequest_request_id = md_ReadRequest.Fields().ByName("request_id") + fd_ReadRequest_destination_chain = md_ReadRequest.Fields().ByName("destination_chain") + fd_ReadRequest_owner = md_ReadRequest.Fields().ByName("owner") + fd_ReadRequest_query = md_ReadRequest.Fields().ByName("query") + fd_ReadRequest_min_confirmations = md_ReadRequest.Fields().ByName("min_confirmations") + fd_ReadRequest_destination_block_height = md_ReadRequest.Fields().ByName("destination_block_height") + fd_ReadRequest_expiry_block_height = md_ReadRequest.Fields().ByName("expiry_block_height") + fd_ReadRequest_created_at_height = md_ReadRequest.Fields().ByName("created_at_height") + fd_ReadRequest_callback_target = md_ReadRequest.Fields().ByName("callback_target") + fd_ReadRequest_original_funder = md_ReadRequest.Fields().ByName("original_funder") + fd_ReadRequest_fees_deposited = md_ReadRequest.Fields().ByName("fees_deposited") + fd_ReadRequest_max_fee = md_ReadRequest.Fields().ByName("max_fee") + fd_ReadRequest_requested_tx_hash = md_ReadRequest.Fields().ByName("requested_tx_hash") + fd_ReadRequest_requested_log_index = md_ReadRequest.Fields().ByName("requested_log_index") +} + +var _ protoreflect.Message = (*fastReflection_ReadRequest)(nil) + +type fastReflection_ReadRequest ReadRequest + +func (x *ReadRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_ReadRequest)(x) +} + +func (x *ReadRequest) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_types_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_ReadRequest_messageType fastReflection_ReadRequest_messageType +var _ protoreflect.MessageType = fastReflection_ReadRequest_messageType{} + +type fastReflection_ReadRequest_messageType struct{} + +func (x fastReflection_ReadRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_ReadRequest)(nil) +} +func (x fastReflection_ReadRequest_messageType) New() protoreflect.Message { + return new(fastReflection_ReadRequest) +} +func (x fastReflection_ReadRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_ReadRequest +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_ReadRequest) Descriptor() protoreflect.MessageDescriptor { + return md_ReadRequest +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_ReadRequest) Type() protoreflect.MessageType { + return _fastReflection_ReadRequest_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_ReadRequest) New() protoreflect.Message { + return new(fastReflection_ReadRequest) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_ReadRequest) Interface() protoreflect.ProtoMessage { + return (*ReadRequest)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_ReadRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.RequestId != "" { + value := protoreflect.ValueOfString(x.RequestId) + if !f(fd_ReadRequest_request_id, value) { + return + } + } + if x.DestinationChain != "" { + value := protoreflect.ValueOfString(x.DestinationChain) + if !f(fd_ReadRequest_destination_chain, value) { + return + } + } + if len(x.Owner) != 0 { + value := protoreflect.ValueOfBytes(x.Owner) + if !f(fd_ReadRequest_owner, value) { + return + } + } + if len(x.Query) != 0 { + value := protoreflect.ValueOfBytes(x.Query) + if !f(fd_ReadRequest_query, value) { + return + } + } + if x.MinConfirmations != uint32(0) { + value := protoreflect.ValueOfUint32(x.MinConfirmations) + if !f(fd_ReadRequest_min_confirmations, value) { + return + } + } + if x.DestinationBlockHeight != uint64(0) { + value := protoreflect.ValueOfUint64(x.DestinationBlockHeight) + if !f(fd_ReadRequest_destination_block_height, value) { + return + } + } + if x.ExpiryBlockHeight != uint64(0) { + value := protoreflect.ValueOfUint64(x.ExpiryBlockHeight) + if !f(fd_ReadRequest_expiry_block_height, value) { + return + } + } + if x.CreatedAtHeight != uint64(0) { + value := protoreflect.ValueOfUint64(x.CreatedAtHeight) + if !f(fd_ReadRequest_created_at_height, value) { + return + } + } + if x.CallbackTarget != "" { + value := protoreflect.ValueOfString(x.CallbackTarget) + if !f(fd_ReadRequest_callback_target, value) { + return + } + } + if x.OriginalFunder != "" { + value := protoreflect.ValueOfString(x.OriginalFunder) + if !f(fd_ReadRequest_original_funder, value) { + return + } + } + if x.FeesDeposited != "" { + value := protoreflect.ValueOfString(x.FeesDeposited) + if !f(fd_ReadRequest_fees_deposited, value) { + return + } + } + if x.MaxFee != "" { + value := protoreflect.ValueOfString(x.MaxFee) + if !f(fd_ReadRequest_max_fee, value) { + return + } + } + if x.RequestedTxHash != "" { + value := protoreflect.ValueOfString(x.RequestedTxHash) + if !f(fd_ReadRequest_requested_tx_hash, value) { + return + } + } + if x.RequestedLogIndex != uint64(0) { + value := protoreflect.ValueOfUint64(x.RequestedLogIndex) + if !f(fd_ReadRequest_requested_log_index, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_ReadRequest) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.ReadRequest.request_id": + return x.RequestId != "" + case "ucallback.v1.ReadRequest.destination_chain": + return x.DestinationChain != "" + case "ucallback.v1.ReadRequest.owner": + return len(x.Owner) != 0 + case "ucallback.v1.ReadRequest.query": + return len(x.Query) != 0 + case "ucallback.v1.ReadRequest.min_confirmations": + return x.MinConfirmations != uint32(0) + case "ucallback.v1.ReadRequest.destination_block_height": + return x.DestinationBlockHeight != uint64(0) + case "ucallback.v1.ReadRequest.expiry_block_height": + return x.ExpiryBlockHeight != uint64(0) + case "ucallback.v1.ReadRequest.created_at_height": + return x.CreatedAtHeight != uint64(0) + case "ucallback.v1.ReadRequest.callback_target": + return x.CallbackTarget != "" + case "ucallback.v1.ReadRequest.original_funder": + return x.OriginalFunder != "" + case "ucallback.v1.ReadRequest.fees_deposited": + return x.FeesDeposited != "" + case "ucallback.v1.ReadRequest.max_fee": + return x.MaxFee != "" + case "ucallback.v1.ReadRequest.requested_tx_hash": + return x.RequestedTxHash != "" + case "ucallback.v1.ReadRequest.requested_log_index": + return x.RequestedLogIndex != uint64(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.ReadRequest")) + } + panic(fmt.Errorf("message ucallback.v1.ReadRequest does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ReadRequest) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.ReadRequest.request_id": + x.RequestId = "" + case "ucallback.v1.ReadRequest.destination_chain": + x.DestinationChain = "" + case "ucallback.v1.ReadRequest.owner": + x.Owner = nil + case "ucallback.v1.ReadRequest.query": + x.Query = nil + case "ucallback.v1.ReadRequest.min_confirmations": + x.MinConfirmations = uint32(0) + case "ucallback.v1.ReadRequest.destination_block_height": + x.DestinationBlockHeight = uint64(0) + case "ucallback.v1.ReadRequest.expiry_block_height": + x.ExpiryBlockHeight = uint64(0) + case "ucallback.v1.ReadRequest.created_at_height": + x.CreatedAtHeight = uint64(0) + case "ucallback.v1.ReadRequest.callback_target": + x.CallbackTarget = "" + case "ucallback.v1.ReadRequest.original_funder": + x.OriginalFunder = "" + case "ucallback.v1.ReadRequest.fees_deposited": + x.FeesDeposited = "" + case "ucallback.v1.ReadRequest.max_fee": + x.MaxFee = "" + case "ucallback.v1.ReadRequest.requested_tx_hash": + x.RequestedTxHash = "" + case "ucallback.v1.ReadRequest.requested_log_index": + x.RequestedLogIndex = uint64(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.ReadRequest")) + } + panic(fmt.Errorf("message ucallback.v1.ReadRequest does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_ReadRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.ReadRequest.request_id": + value := x.RequestId + return protoreflect.ValueOfString(value) + case "ucallback.v1.ReadRequest.destination_chain": + value := x.DestinationChain + return protoreflect.ValueOfString(value) + case "ucallback.v1.ReadRequest.owner": + value := x.Owner + return protoreflect.ValueOfBytes(value) + case "ucallback.v1.ReadRequest.query": + value := x.Query + return protoreflect.ValueOfBytes(value) + case "ucallback.v1.ReadRequest.min_confirmations": + value := x.MinConfirmations + return protoreflect.ValueOfUint32(value) + case "ucallback.v1.ReadRequest.destination_block_height": + value := x.DestinationBlockHeight + return protoreflect.ValueOfUint64(value) + case "ucallback.v1.ReadRequest.expiry_block_height": + value := x.ExpiryBlockHeight + return protoreflect.ValueOfUint64(value) + case "ucallback.v1.ReadRequest.created_at_height": + value := x.CreatedAtHeight + return protoreflect.ValueOfUint64(value) + case "ucallback.v1.ReadRequest.callback_target": + value := x.CallbackTarget + return protoreflect.ValueOfString(value) + case "ucallback.v1.ReadRequest.original_funder": + value := x.OriginalFunder + return protoreflect.ValueOfString(value) + case "ucallback.v1.ReadRequest.fees_deposited": + value := x.FeesDeposited + return protoreflect.ValueOfString(value) + case "ucallback.v1.ReadRequest.max_fee": + value := x.MaxFee + return protoreflect.ValueOfString(value) + case "ucallback.v1.ReadRequest.requested_tx_hash": + value := x.RequestedTxHash + return protoreflect.ValueOfString(value) + case "ucallback.v1.ReadRequest.requested_log_index": + value := x.RequestedLogIndex + return protoreflect.ValueOfUint64(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.ReadRequest")) + } + panic(fmt.Errorf("message ucallback.v1.ReadRequest does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ReadRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.ReadRequest.request_id": + x.RequestId = value.Interface().(string) + case "ucallback.v1.ReadRequest.destination_chain": + x.DestinationChain = value.Interface().(string) + case "ucallback.v1.ReadRequest.owner": + x.Owner = value.Bytes() + case "ucallback.v1.ReadRequest.query": + x.Query = value.Bytes() + case "ucallback.v1.ReadRequest.min_confirmations": + x.MinConfirmations = uint32(value.Uint()) + case "ucallback.v1.ReadRequest.destination_block_height": + x.DestinationBlockHeight = value.Uint() + case "ucallback.v1.ReadRequest.expiry_block_height": + x.ExpiryBlockHeight = value.Uint() + case "ucallback.v1.ReadRequest.created_at_height": + x.CreatedAtHeight = value.Uint() + case "ucallback.v1.ReadRequest.callback_target": + x.CallbackTarget = value.Interface().(string) + case "ucallback.v1.ReadRequest.original_funder": + x.OriginalFunder = value.Interface().(string) + case "ucallback.v1.ReadRequest.fees_deposited": + x.FeesDeposited = value.Interface().(string) + case "ucallback.v1.ReadRequest.max_fee": + x.MaxFee = value.Interface().(string) + case "ucallback.v1.ReadRequest.requested_tx_hash": + x.RequestedTxHash = value.Interface().(string) + case "ucallback.v1.ReadRequest.requested_log_index": + x.RequestedLogIndex = value.Uint() + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.ReadRequest")) + } + panic(fmt.Errorf("message ucallback.v1.ReadRequest does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ReadRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.ReadRequest.request_id": + panic(fmt.Errorf("field request_id of message ucallback.v1.ReadRequest is not mutable")) + case "ucallback.v1.ReadRequest.destination_chain": + panic(fmt.Errorf("field destination_chain of message ucallback.v1.ReadRequest is not mutable")) + case "ucallback.v1.ReadRequest.owner": + panic(fmt.Errorf("field owner of message ucallback.v1.ReadRequest is not mutable")) + case "ucallback.v1.ReadRequest.query": + panic(fmt.Errorf("field query of message ucallback.v1.ReadRequest is not mutable")) + case "ucallback.v1.ReadRequest.min_confirmations": + panic(fmt.Errorf("field min_confirmations of message ucallback.v1.ReadRequest is not mutable")) + case "ucallback.v1.ReadRequest.destination_block_height": + panic(fmt.Errorf("field destination_block_height of message ucallback.v1.ReadRequest is not mutable")) + case "ucallback.v1.ReadRequest.expiry_block_height": + panic(fmt.Errorf("field expiry_block_height of message ucallback.v1.ReadRequest is not mutable")) + case "ucallback.v1.ReadRequest.created_at_height": + panic(fmt.Errorf("field created_at_height of message ucallback.v1.ReadRequest is not mutable")) + case "ucallback.v1.ReadRequest.callback_target": + panic(fmt.Errorf("field callback_target of message ucallback.v1.ReadRequest is not mutable")) + case "ucallback.v1.ReadRequest.original_funder": + panic(fmt.Errorf("field original_funder of message ucallback.v1.ReadRequest is not mutable")) + case "ucallback.v1.ReadRequest.fees_deposited": + panic(fmt.Errorf("field fees_deposited of message ucallback.v1.ReadRequest is not mutable")) + case "ucallback.v1.ReadRequest.max_fee": + panic(fmt.Errorf("field max_fee of message ucallback.v1.ReadRequest is not mutable")) + case "ucallback.v1.ReadRequest.requested_tx_hash": + panic(fmt.Errorf("field requested_tx_hash of message ucallback.v1.ReadRequest is not mutable")) + case "ucallback.v1.ReadRequest.requested_log_index": + panic(fmt.Errorf("field requested_log_index of message ucallback.v1.ReadRequest is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.ReadRequest")) + } + panic(fmt.Errorf("message ucallback.v1.ReadRequest does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_ReadRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.ReadRequest.request_id": + return protoreflect.ValueOfString("") + case "ucallback.v1.ReadRequest.destination_chain": + return protoreflect.ValueOfString("") + case "ucallback.v1.ReadRequest.owner": + return protoreflect.ValueOfBytes(nil) + case "ucallback.v1.ReadRequest.query": + return protoreflect.ValueOfBytes(nil) + case "ucallback.v1.ReadRequest.min_confirmations": + return protoreflect.ValueOfUint32(uint32(0)) + case "ucallback.v1.ReadRequest.destination_block_height": + return protoreflect.ValueOfUint64(uint64(0)) + case "ucallback.v1.ReadRequest.expiry_block_height": + return protoreflect.ValueOfUint64(uint64(0)) + case "ucallback.v1.ReadRequest.created_at_height": + return protoreflect.ValueOfUint64(uint64(0)) + case "ucallback.v1.ReadRequest.callback_target": + return protoreflect.ValueOfString("") + case "ucallback.v1.ReadRequest.original_funder": + return protoreflect.ValueOfString("") + case "ucallback.v1.ReadRequest.fees_deposited": + return protoreflect.ValueOfString("") + case "ucallback.v1.ReadRequest.max_fee": + return protoreflect.ValueOfString("") + case "ucallback.v1.ReadRequest.requested_tx_hash": + return protoreflect.ValueOfString("") + case "ucallback.v1.ReadRequest.requested_log_index": + return protoreflect.ValueOfUint64(uint64(0)) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.ReadRequest")) + } + panic(fmt.Errorf("message ucallback.v1.ReadRequest does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_ReadRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.ReadRequest", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_ReadRequest) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ReadRequest) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_ReadRequest) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_ReadRequest) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*ReadRequest) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.RequestId) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.DestinationChain) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Owner) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Query) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.MinConfirmations != 0 { + n += 1 + runtime.Sov(uint64(x.MinConfirmations)) + } + if x.DestinationBlockHeight != 0 { + n += 1 + runtime.Sov(uint64(x.DestinationBlockHeight)) + } + if x.ExpiryBlockHeight != 0 { + n += 1 + runtime.Sov(uint64(x.ExpiryBlockHeight)) + } + if x.CreatedAtHeight != 0 { + n += 1 + runtime.Sov(uint64(x.CreatedAtHeight)) + } + l = len(x.CallbackTarget) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.OriginalFunder) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.FeesDeposited) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.MaxFee) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.RequestedTxHash) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.RequestedLogIndex != 0 { + n += 1 + runtime.Sov(uint64(x.RequestedLogIndex)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*ReadRequest) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.RequestedLogIndex != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.RequestedLogIndex)) + i-- + dAtA[i] = 0x70 + } + if len(x.RequestedTxHash) > 0 { + i -= len(x.RequestedTxHash) + copy(dAtA[i:], x.RequestedTxHash) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.RequestedTxHash))) + i-- + dAtA[i] = 0x6a + } + if len(x.MaxFee) > 0 { + i -= len(x.MaxFee) + copy(dAtA[i:], x.MaxFee) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.MaxFee))) + i-- + dAtA[i] = 0x62 + } + if len(x.FeesDeposited) > 0 { + i -= len(x.FeesDeposited) + copy(dAtA[i:], x.FeesDeposited) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.FeesDeposited))) + i-- + dAtA[i] = 0x5a + } + if len(x.OriginalFunder) > 0 { + i -= len(x.OriginalFunder) + copy(dAtA[i:], x.OriginalFunder) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.OriginalFunder))) + i-- + dAtA[i] = 0x52 + } + if len(x.CallbackTarget) > 0 { + i -= len(x.CallbackTarget) + copy(dAtA[i:], x.CallbackTarget) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.CallbackTarget))) + i-- + dAtA[i] = 0x4a + } + if x.CreatedAtHeight != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.CreatedAtHeight)) + i-- + dAtA[i] = 0x40 + } + if x.ExpiryBlockHeight != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.ExpiryBlockHeight)) + i-- + dAtA[i] = 0x38 + } + if x.DestinationBlockHeight != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.DestinationBlockHeight)) + i-- + dAtA[i] = 0x30 + } + if x.MinConfirmations != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.MinConfirmations)) + i-- + dAtA[i] = 0x28 + } + if len(x.Query) > 0 { + i -= len(x.Query) + copy(dAtA[i:], x.Query) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Query))) + i-- + dAtA[i] = 0x22 + } + if len(x.Owner) > 0 { + i -= len(x.Owner) + copy(dAtA[i:], x.Owner) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Owner))) + i-- + dAtA[i] = 0x1a + } + if len(x.DestinationChain) > 0 { + i -= len(x.DestinationChain) + copy(dAtA[i:], x.DestinationChain) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.DestinationChain))) + i-- + dAtA[i] = 0x12 + } + if len(x.RequestId) > 0 { + i -= len(x.RequestId) + copy(dAtA[i:], x.RequestId) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.RequestId))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*ReadRequest) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ReadRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ReadRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field RequestId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.RequestId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field DestinationChain", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.DestinationChain = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Owner = append(x.Owner[:0], dAtA[iNdEx:postIndex]...) + if x.Owner == nil { + x.Owner = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Query = append(x.Query[:0], dAtA[iNdEx:postIndex]...) + if x.Query == nil { + x.Query = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field MinConfirmations", wireType) + } + x.MinConfirmations = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.MinConfirmations |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field DestinationBlockHeight", wireType) + } + x.DestinationBlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.DestinationBlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExpiryBlockHeight", wireType) + } + x.ExpiryBlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.ExpiryBlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CreatedAtHeight", wireType) + } + x.CreatedAtHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.CreatedAtHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 9: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CallbackTarget", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.CallbackTarget = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field OriginalFunder", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.OriginalFunder = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 11: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field FeesDeposited", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.FeesDeposited = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 12: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field MaxFee", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.MaxFee = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 13: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field RequestedTxHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.RequestedTxHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 14: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field RequestedLogIndex", wireType) + } + x.RequestedLogIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.RequestedLogIndex |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var _ protoreflect.List = (*_ReadResult_5_list)(nil) + +type _ReadResult_5_list struct { + list *[]*AggregateValue +} + +func (x *_ReadResult_5_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_ReadResult_5_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) +} + +func (x *_ReadResult_5_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*AggregateValue) + (*x.list)[i] = concreteValue +} + +func (x *_ReadResult_5_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*AggregateValue) + *x.list = append(*x.list, concreteValue) +} + +func (x *_ReadResult_5_list) AppendMutable() protoreflect.Value { + v := new(AggregateValue) + *x.list = append(*x.list, v) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_ReadResult_5_list) Truncate(n int) { + for i := n; i < len(*x.list); i++ { + (*x.list)[i] = nil + } + *x.list = (*x.list)[:n] +} + +func (x *_ReadResult_5_list) NewElement() protoreflect.Value { + v := new(AggregateValue) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_ReadResult_5_list) IsValid() bool { + return x.list != nil +} + +var ( + md_ReadResult protoreflect.MessageDescriptor + fd_ReadResult_status protoreflect.FieldDescriptor + fd_ReadResult_result_data protoreflect.FieldDescriptor + fd_ReadResult_observed_block_height protoreflect.FieldDescriptor + fd_ReadResult_observed_block_hash protoreflect.FieldDescriptor + fd_ReadResult_aggregates protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_types_proto_init() + md_ReadResult = File_ucallback_v1_types_proto.Messages().ByName("ReadResult") + fd_ReadResult_status = md_ReadResult.Fields().ByName("status") + fd_ReadResult_result_data = md_ReadResult.Fields().ByName("result_data") + fd_ReadResult_observed_block_height = md_ReadResult.Fields().ByName("observed_block_height") + fd_ReadResult_observed_block_hash = md_ReadResult.Fields().ByName("observed_block_hash") + fd_ReadResult_aggregates = md_ReadResult.Fields().ByName("aggregates") +} + +var _ protoreflect.Message = (*fastReflection_ReadResult)(nil) + +type fastReflection_ReadResult ReadResult + +func (x *ReadResult) ProtoReflect() protoreflect.Message { + return (*fastReflection_ReadResult)(x) +} + +func (x *ReadResult) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_types_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_ReadResult_messageType fastReflection_ReadResult_messageType +var _ protoreflect.MessageType = fastReflection_ReadResult_messageType{} + +type fastReflection_ReadResult_messageType struct{} + +func (x fastReflection_ReadResult_messageType) Zero() protoreflect.Message { + return (*fastReflection_ReadResult)(nil) +} +func (x fastReflection_ReadResult_messageType) New() protoreflect.Message { + return new(fastReflection_ReadResult) +} +func (x fastReflection_ReadResult_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_ReadResult +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_ReadResult) Descriptor() protoreflect.MessageDescriptor { + return md_ReadResult +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_ReadResult) Type() protoreflect.MessageType { + return _fastReflection_ReadResult_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_ReadResult) New() protoreflect.Message { + return new(fastReflection_ReadResult) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_ReadResult) Interface() protoreflect.ProtoMessage { + return (*ReadResult)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_ReadResult) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Status != 0 { + value := protoreflect.ValueOfEnum((protoreflect.EnumNumber)(x.Status)) + if !f(fd_ReadResult_status, value) { + return + } + } + if len(x.ResultData) != 0 { + value := protoreflect.ValueOfBytes(x.ResultData) + if !f(fd_ReadResult_result_data, value) { + return + } + } + if x.ObservedBlockHeight != uint64(0) { + value := protoreflect.ValueOfUint64(x.ObservedBlockHeight) + if !f(fd_ReadResult_observed_block_height, value) { + return + } + } + if len(x.ObservedBlockHash) != 0 { + value := protoreflect.ValueOfBytes(x.ObservedBlockHash) + if !f(fd_ReadResult_observed_block_hash, value) { + return + } + } + if len(x.Aggregates) != 0 { + value := protoreflect.ValueOfList(&_ReadResult_5_list{list: &x.Aggregates}) + if !f(fd_ReadResult_aggregates, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_ReadResult) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.ReadResult.status": + return x.Status != 0 + case "ucallback.v1.ReadResult.result_data": + return len(x.ResultData) != 0 + case "ucallback.v1.ReadResult.observed_block_height": + return x.ObservedBlockHeight != uint64(0) + case "ucallback.v1.ReadResult.observed_block_hash": + return len(x.ObservedBlockHash) != 0 + case "ucallback.v1.ReadResult.aggregates": + return len(x.Aggregates) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.ReadResult")) + } + panic(fmt.Errorf("message ucallback.v1.ReadResult does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ReadResult) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.ReadResult.status": + x.Status = 0 + case "ucallback.v1.ReadResult.result_data": + x.ResultData = nil + case "ucallback.v1.ReadResult.observed_block_height": + x.ObservedBlockHeight = uint64(0) + case "ucallback.v1.ReadResult.observed_block_hash": + x.ObservedBlockHash = nil + case "ucallback.v1.ReadResult.aggregates": + x.Aggregates = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.ReadResult")) + } + panic(fmt.Errorf("message ucallback.v1.ReadResult does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_ReadResult) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.ReadResult.status": + value := x.Status + return protoreflect.ValueOfEnum((protoreflect.EnumNumber)(value)) + case "ucallback.v1.ReadResult.result_data": + value := x.ResultData + return protoreflect.ValueOfBytes(value) + case "ucallback.v1.ReadResult.observed_block_height": + value := x.ObservedBlockHeight + return protoreflect.ValueOfUint64(value) + case "ucallback.v1.ReadResult.observed_block_hash": + value := x.ObservedBlockHash + return protoreflect.ValueOfBytes(value) + case "ucallback.v1.ReadResult.aggregates": + if len(x.Aggregates) == 0 { + return protoreflect.ValueOfList(&_ReadResult_5_list{}) + } + listValue := &_ReadResult_5_list{list: &x.Aggregates} + return protoreflect.ValueOfList(listValue) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.ReadResult")) + } + panic(fmt.Errorf("message ucallback.v1.ReadResult does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ReadResult) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.ReadResult.status": + x.Status = (ReadStatus)(value.Enum()) + case "ucallback.v1.ReadResult.result_data": + x.ResultData = value.Bytes() + case "ucallback.v1.ReadResult.observed_block_height": + x.ObservedBlockHeight = value.Uint() + case "ucallback.v1.ReadResult.observed_block_hash": + x.ObservedBlockHash = value.Bytes() + case "ucallback.v1.ReadResult.aggregates": + lv := value.List() + clv := lv.(*_ReadResult_5_list) + x.Aggregates = *clv.list + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.ReadResult")) + } + panic(fmt.Errorf("message ucallback.v1.ReadResult does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ReadResult) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.ReadResult.aggregates": + if x.Aggregates == nil { + x.Aggregates = []*AggregateValue{} + } + value := &_ReadResult_5_list{list: &x.Aggregates} + return protoreflect.ValueOfList(value) + case "ucallback.v1.ReadResult.status": + panic(fmt.Errorf("field status of message ucallback.v1.ReadResult is not mutable")) + case "ucallback.v1.ReadResult.result_data": + panic(fmt.Errorf("field result_data of message ucallback.v1.ReadResult is not mutable")) + case "ucallback.v1.ReadResult.observed_block_height": + panic(fmt.Errorf("field observed_block_height of message ucallback.v1.ReadResult is not mutable")) + case "ucallback.v1.ReadResult.observed_block_hash": + panic(fmt.Errorf("field observed_block_hash of message ucallback.v1.ReadResult is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.ReadResult")) + } + panic(fmt.Errorf("message ucallback.v1.ReadResult does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_ReadResult) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.ReadResult.status": + return protoreflect.ValueOfEnum(0) + case "ucallback.v1.ReadResult.result_data": + return protoreflect.ValueOfBytes(nil) + case "ucallback.v1.ReadResult.observed_block_height": + return protoreflect.ValueOfUint64(uint64(0)) + case "ucallback.v1.ReadResult.observed_block_hash": + return protoreflect.ValueOfBytes(nil) + case "ucallback.v1.ReadResult.aggregates": + list := []*AggregateValue{} + return protoreflect.ValueOfList(&_ReadResult_5_list{list: &list}) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.ReadResult")) + } + panic(fmt.Errorf("message ucallback.v1.ReadResult does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_ReadResult) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.ReadResult", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_ReadResult) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_ReadResult) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_ReadResult) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_ReadResult) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*ReadResult) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.Status != 0 { + n += 1 + runtime.Sov(uint64(x.Status)) + } + l = len(x.ResultData) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.ObservedBlockHeight != 0 { + n += 1 + runtime.Sov(uint64(x.ObservedBlockHeight)) + } + l = len(x.ObservedBlockHash) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if len(x.Aggregates) > 0 { + for _, e := range x.Aggregates { + l = options.Size(e) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*ReadResult) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Aggregates) > 0 { + for iNdEx := len(x.Aggregates) - 1; iNdEx >= 0; iNdEx-- { + encoded, err := options.Marshal(x.Aggregates[iNdEx]) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x2a + } + } + if len(x.ObservedBlockHash) > 0 { + i -= len(x.ObservedBlockHash) + copy(dAtA[i:], x.ObservedBlockHash) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ObservedBlockHash))) + i-- + dAtA[i] = 0x22 + } + if x.ObservedBlockHeight != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.ObservedBlockHeight)) + i-- + dAtA[i] = 0x18 + } + if len(x.ResultData) > 0 { + i -= len(x.ResultData) + copy(dAtA[i:], x.ResultData) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ResultData))) + i-- + dAtA[i] = 0x12 + } + if x.Status != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.Status)) + i-- + dAtA[i] = 0x8 + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*ReadResult) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ReadResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: ReadResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + x.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.Status |= ReadStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ResultData", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.ResultData = append(x.ResultData[:0], dAtA[iNdEx:postIndex]...) + if x.ResultData == nil { + x.ResultData = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ObservedBlockHeight", wireType) + } + x.ObservedBlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.ObservedBlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ObservedBlockHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.ObservedBlockHash = append(x.ObservedBlockHash[:0], dAtA[iNdEx:postIndex]...) + if x.ObservedBlockHash == nil { + x.ObservedBlockHash = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Aggregates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Aggregates = append(x.Aggregates, &AggregateValue{}) + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Aggregates[len(x.Aggregates)-1]); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var ( + md_AggregateValue protoreflect.MessageDescriptor + fd_AggregateValue_extract_index protoreflect.FieldDescriptor + fd_AggregateValue_mode protoreflect.FieldDescriptor + fd_AggregateValue_value protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_types_proto_init() + md_AggregateValue = File_ucallback_v1_types_proto.Messages().ByName("AggregateValue") + fd_AggregateValue_extract_index = md_AggregateValue.Fields().ByName("extract_index") + fd_AggregateValue_mode = md_AggregateValue.Fields().ByName("mode") + fd_AggregateValue_value = md_AggregateValue.Fields().ByName("value") +} + +var _ protoreflect.Message = (*fastReflection_AggregateValue)(nil) + +type fastReflection_AggregateValue AggregateValue + +func (x *AggregateValue) ProtoReflect() protoreflect.Message { + return (*fastReflection_AggregateValue)(x) +} + +func (x *AggregateValue) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_types_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_AggregateValue_messageType fastReflection_AggregateValue_messageType +var _ protoreflect.MessageType = fastReflection_AggregateValue_messageType{} + +type fastReflection_AggregateValue_messageType struct{} + +func (x fastReflection_AggregateValue_messageType) Zero() protoreflect.Message { + return (*fastReflection_AggregateValue)(nil) +} +func (x fastReflection_AggregateValue_messageType) New() protoreflect.Message { + return new(fastReflection_AggregateValue) +} +func (x fastReflection_AggregateValue_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_AggregateValue +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_AggregateValue) Descriptor() protoreflect.MessageDescriptor { + return md_AggregateValue +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_AggregateValue) Type() protoreflect.MessageType { + return _fastReflection_AggregateValue_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_AggregateValue) New() protoreflect.Message { + return new(fastReflection_AggregateValue) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_AggregateValue) Interface() protoreflect.ProtoMessage { + return (*AggregateValue)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_AggregateValue) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.ExtractIndex != uint32(0) { + value := protoreflect.ValueOfUint32(x.ExtractIndex) + if !f(fd_AggregateValue_extract_index, value) { + return + } + } + if x.Mode != uint32(0) { + value := protoreflect.ValueOfUint32(x.Mode) + if !f(fd_AggregateValue_mode, value) { + return + } + } + if len(x.Value) != 0 { + value := protoreflect.ValueOfBytes(x.Value) + if !f(fd_AggregateValue_value, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_AggregateValue) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.AggregateValue.extract_index": + return x.ExtractIndex != uint32(0) + case "ucallback.v1.AggregateValue.mode": + return x.Mode != uint32(0) + case "ucallback.v1.AggregateValue.value": + return len(x.Value) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.AggregateValue")) + } + panic(fmt.Errorf("message ucallback.v1.AggregateValue does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_AggregateValue) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.AggregateValue.extract_index": + x.ExtractIndex = uint32(0) + case "ucallback.v1.AggregateValue.mode": + x.Mode = uint32(0) + case "ucallback.v1.AggregateValue.value": + x.Value = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.AggregateValue")) + } + panic(fmt.Errorf("message ucallback.v1.AggregateValue does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_AggregateValue) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.AggregateValue.extract_index": + value := x.ExtractIndex + return protoreflect.ValueOfUint32(value) + case "ucallback.v1.AggregateValue.mode": + value := x.Mode + return protoreflect.ValueOfUint32(value) + case "ucallback.v1.AggregateValue.value": + value := x.Value + return protoreflect.ValueOfBytes(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.AggregateValue")) + } + panic(fmt.Errorf("message ucallback.v1.AggregateValue does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_AggregateValue) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.AggregateValue.extract_index": + x.ExtractIndex = uint32(value.Uint()) + case "ucallback.v1.AggregateValue.mode": + x.Mode = uint32(value.Uint()) + case "ucallback.v1.AggregateValue.value": + x.Value = value.Bytes() + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.AggregateValue")) + } + panic(fmt.Errorf("message ucallback.v1.AggregateValue does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_AggregateValue) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.AggregateValue.extract_index": + panic(fmt.Errorf("field extract_index of message ucallback.v1.AggregateValue is not mutable")) + case "ucallback.v1.AggregateValue.mode": + panic(fmt.Errorf("field mode of message ucallback.v1.AggregateValue is not mutable")) + case "ucallback.v1.AggregateValue.value": + panic(fmt.Errorf("field value of message ucallback.v1.AggregateValue is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.AggregateValue")) + } + panic(fmt.Errorf("message ucallback.v1.AggregateValue does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_AggregateValue) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.AggregateValue.extract_index": + return protoreflect.ValueOfUint32(uint32(0)) + case "ucallback.v1.AggregateValue.mode": + return protoreflect.ValueOfUint32(uint32(0)) + case "ucallback.v1.AggregateValue.value": + return protoreflect.ValueOfBytes(nil) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.AggregateValue")) + } + panic(fmt.Errorf("message ucallback.v1.AggregateValue does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_AggregateValue) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.AggregateValue", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_AggregateValue) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_AggregateValue) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_AggregateValue) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_AggregateValue) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*AggregateValue) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if x.ExtractIndex != 0 { + n += 1 + runtime.Sov(uint64(x.ExtractIndex)) + } + if x.Mode != 0 { + n += 1 + runtime.Sov(uint64(x.Mode)) + } + l = len(x.Value) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*AggregateValue) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.Value) > 0 { + i -= len(x.Value) + copy(dAtA[i:], x.Value) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Value))) + i-- + dAtA[i] = 0x1a + } + if x.Mode != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.Mode)) + i-- + dAtA[i] = 0x10 + } + if x.ExtractIndex != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.ExtractIndex)) + i-- + dAtA[i] = 0x8 + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*AggregateValue) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: AggregateValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: AggregateValue: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExtractIndex", wireType) + } + x.ExtractIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.ExtractIndex |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType) + } + x.Mode = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.Mode |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Value = append(x.Value[:0], dAtA[iNdEx:postIndex]...) + if x.Value == nil { + x.Value = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +var _ protoreflect.List = (*_UniversalRead_6_list)(nil) + +type _UniversalRead_6_list struct { + list *[]*v1.PCTx +} + +func (x *_UniversalRead_6_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_UniversalRead_6_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) +} + +func (x *_UniversalRead_6_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*v1.PCTx) + (*x.list)[i] = concreteValue +} + +func (x *_UniversalRead_6_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*v1.PCTx) + *x.list = append(*x.list, concreteValue) +} + +func (x *_UniversalRead_6_list) AppendMutable() protoreflect.Value { + v := new(v1.PCTx) + *x.list = append(*x.list, v) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_UniversalRead_6_list) Truncate(n int) { + for i := n; i < len(*x.list); i++ { + (*x.list)[i] = nil + } + *x.list = (*x.list)[:n] +} + +func (x *_UniversalRead_6_list) NewElement() protoreflect.Value { + v := new(v1.PCTx) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_UniversalRead_6_list) IsValid() bool { + return x.list != nil +} + +var ( + md_UniversalRead protoreflect.MessageDescriptor + fd_UniversalRead_id protoreflect.FieldDescriptor + fd_UniversalRead_request protoreflect.FieldDescriptor + fd_UniversalRead_result protoreflect.FieldDescriptor + fd_UniversalRead_status protoreflect.FieldDescriptor + fd_UniversalRead_ballot_key protoreflect.FieldDescriptor + fd_UniversalRead_pc_tx protoreflect.FieldDescriptor +) + +func init() { + file_ucallback_v1_types_proto_init() + md_UniversalRead = File_ucallback_v1_types_proto.Messages().ByName("UniversalRead") + fd_UniversalRead_id = md_UniversalRead.Fields().ByName("id") + fd_UniversalRead_request = md_UniversalRead.Fields().ByName("request") + fd_UniversalRead_result = md_UniversalRead.Fields().ByName("result") + fd_UniversalRead_status = md_UniversalRead.Fields().ByName("status") + fd_UniversalRead_ballot_key = md_UniversalRead.Fields().ByName("ballot_key") + fd_UniversalRead_pc_tx = md_UniversalRead.Fields().ByName("pc_tx") +} + +var _ protoreflect.Message = (*fastReflection_UniversalRead)(nil) + +type fastReflection_UniversalRead UniversalRead + +func (x *UniversalRead) ProtoReflect() protoreflect.Message { + return (*fastReflection_UniversalRead)(x) +} + +func (x *UniversalRead) slowProtoReflect() protoreflect.Message { + mi := &file_ucallback_v1_types_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_UniversalRead_messageType fastReflection_UniversalRead_messageType +var _ protoreflect.MessageType = fastReflection_UniversalRead_messageType{} + +type fastReflection_UniversalRead_messageType struct{} + +func (x fastReflection_UniversalRead_messageType) Zero() protoreflect.Message { + return (*fastReflection_UniversalRead)(nil) +} +func (x fastReflection_UniversalRead_messageType) New() protoreflect.Message { + return new(fastReflection_UniversalRead) +} +func (x fastReflection_UniversalRead_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_UniversalRead +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_UniversalRead) Descriptor() protoreflect.MessageDescriptor { + return md_UniversalRead +} + +// Type returns the message type, which encapsulates both Go and protobuf +// type information. If the Go type information is not needed, +// it is recommended that the message descriptor be used instead. +func (x *fastReflection_UniversalRead) Type() protoreflect.MessageType { + return _fastReflection_UniversalRead_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_UniversalRead) New() protoreflect.Message { + return new(fastReflection_UniversalRead) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_UniversalRead) Interface() protoreflect.ProtoMessage { + return (*UniversalRead)(x) +} + +// Range iterates over every populated field in an undefined order, +// calling f for each field descriptor and value encountered. +// Range returns immediately if f returns false. +// While iterating, mutating operations may only be performed +// on the current field descriptor. +func (x *fastReflection_UniversalRead) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Id != "" { + value := protoreflect.ValueOfString(x.Id) + if !f(fd_UniversalRead_id, value) { + return + } + } + if x.Request != nil { + value := protoreflect.ValueOfMessage(x.Request.ProtoReflect()) + if !f(fd_UniversalRead_request, value) { + return + } + } + if x.Result != nil { + value := protoreflect.ValueOfMessage(x.Result.ProtoReflect()) + if !f(fd_UniversalRead_result, value) { + return + } + } + if x.Status != 0 { + value := protoreflect.ValueOfEnum((protoreflect.EnumNumber)(x.Status)) + if !f(fd_UniversalRead_status, value) { + return + } + } + if x.BallotKey != "" { + value := protoreflect.ValueOfString(x.BallotKey) + if !f(fd_UniversalRead_ballot_key, value) { + return + } + } + if len(x.PcTx) != 0 { + value := protoreflect.ValueOfList(&_UniversalRead_6_list{list: &x.PcTx}) + if !f(fd_UniversalRead_pc_tx, value) { + return + } + } +} + +// Has reports whether a field is populated. +// +// Some fields have the property of nullability where it is possible to +// distinguish between the default value of a field and whether the field +// was explicitly populated with the default value. Singular message fields, +// member fields of a oneof, and proto2 scalar fields are nullable. Such +// fields are populated only if explicitly set. +// +// In other cases (aside from the nullable cases above), +// a proto3 scalar field is populated if it contains a non-zero value, and +// a repeated field is populated if it is non-empty. +func (x *fastReflection_UniversalRead) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "ucallback.v1.UniversalRead.id": + return x.Id != "" + case "ucallback.v1.UniversalRead.request": + return x.Request != nil + case "ucallback.v1.UniversalRead.result": + return x.Result != nil + case "ucallback.v1.UniversalRead.status": + return x.Status != 0 + case "ucallback.v1.UniversalRead.ballot_key": + return x.BallotKey != "" + case "ucallback.v1.UniversalRead.pc_tx": + return len(x.PcTx) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.UniversalRead")) + } + panic(fmt.Errorf("message ucallback.v1.UniversalRead does not contain field %s", fd.FullName())) + } +} + +// Clear clears the field such that a subsequent Has call reports false. +// +// Clearing an extension field clears both the extension type and value +// associated with the given field number. +// +// Clear is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_UniversalRead) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "ucallback.v1.UniversalRead.id": + x.Id = "" + case "ucallback.v1.UniversalRead.request": + x.Request = nil + case "ucallback.v1.UniversalRead.result": + x.Result = nil + case "ucallback.v1.UniversalRead.status": + x.Status = 0 + case "ucallback.v1.UniversalRead.ballot_key": + x.BallotKey = "" + case "ucallback.v1.UniversalRead.pc_tx": + x.PcTx = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.UniversalRead")) + } + panic(fmt.Errorf("message ucallback.v1.UniversalRead does not contain field %s", fd.FullName())) + } +} + +// Get retrieves the value for a field. +// +// For unpopulated scalars, it returns the default value, where +// the default value of a bytes scalar is guaranteed to be a copy. +// For unpopulated composite types, it returns an empty, read-only view +// of the value; to obtain a mutable reference, use Mutable. +func (x *fastReflection_UniversalRead) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "ucallback.v1.UniversalRead.id": + value := x.Id + return protoreflect.ValueOfString(value) + case "ucallback.v1.UniversalRead.request": + value := x.Request + return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "ucallback.v1.UniversalRead.result": + value := x.Result + return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "ucallback.v1.UniversalRead.status": + value := x.Status + return protoreflect.ValueOfEnum((protoreflect.EnumNumber)(value)) + case "ucallback.v1.UniversalRead.ballot_key": + value := x.BallotKey + return protoreflect.ValueOfString(value) + case "ucallback.v1.UniversalRead.pc_tx": + if len(x.PcTx) == 0 { + return protoreflect.ValueOfList(&_UniversalRead_6_list{}) + } + listValue := &_UniversalRead_6_list{list: &x.PcTx} + return protoreflect.ValueOfList(listValue) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.UniversalRead")) + } + panic(fmt.Errorf("message ucallback.v1.UniversalRead does not contain field %s", descriptor.FullName())) + } +} + +// Set stores the value for a field. +// +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType. +// When setting a composite type, it is unspecified whether the stored value +// aliases the source's memory in any way. If the composite value is an +// empty, read-only value, then it panics. +// +// Set is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_UniversalRead) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "ucallback.v1.UniversalRead.id": + x.Id = value.Interface().(string) + case "ucallback.v1.UniversalRead.request": + x.Request = value.Message().Interface().(*ReadRequest) + case "ucallback.v1.UniversalRead.result": + x.Result = value.Message().Interface().(*ReadResult) + case "ucallback.v1.UniversalRead.status": + x.Status = (UniversalReadStatus)(value.Enum()) + case "ucallback.v1.UniversalRead.ballot_key": + x.BallotKey = value.Interface().(string) + case "ucallback.v1.UniversalRead.pc_tx": + lv := value.List() + clv := lv.(*_UniversalRead_6_list) + x.PcTx = *clv.list + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.UniversalRead")) + } + panic(fmt.Errorf("message ucallback.v1.UniversalRead does not contain field %s", fd.FullName())) + } +} + +// Mutable returns a mutable reference to a composite type. +// +// If the field is unpopulated, it may allocate a composite value. +// For a field belonging to a oneof, it implicitly clears any other field +// that may be currently set within the same oneof. +// For extension fields, it implicitly stores the provided ExtensionType +// if not already stored. +// It panics if the field does not contain a composite type. +// +// Mutable is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_UniversalRead) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.UniversalRead.request": + if x.Request == nil { + x.Request = new(ReadRequest) + } + return protoreflect.ValueOfMessage(x.Request.ProtoReflect()) + case "ucallback.v1.UniversalRead.result": + if x.Result == nil { + x.Result = new(ReadResult) + } + return protoreflect.ValueOfMessage(x.Result.ProtoReflect()) + case "ucallback.v1.UniversalRead.pc_tx": + if x.PcTx == nil { + x.PcTx = []*v1.PCTx{} + } + value := &_UniversalRead_6_list{list: &x.PcTx} + return protoreflect.ValueOfList(value) + case "ucallback.v1.UniversalRead.id": + panic(fmt.Errorf("field id of message ucallback.v1.UniversalRead is not mutable")) + case "ucallback.v1.UniversalRead.status": + panic(fmt.Errorf("field status of message ucallback.v1.UniversalRead is not mutable")) + case "ucallback.v1.UniversalRead.ballot_key": + panic(fmt.Errorf("field ballot_key of message ucallback.v1.UniversalRead is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.UniversalRead")) + } + panic(fmt.Errorf("message ucallback.v1.UniversalRead does not contain field %s", fd.FullName())) + } +} + +// NewField returns a new value that is assignable to the field +// for the given descriptor. For scalars, this returns the default value. +// For lists, maps, and messages, this returns a new, empty, mutable value. +func (x *fastReflection_UniversalRead) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "ucallback.v1.UniversalRead.id": + return protoreflect.ValueOfString("") + case "ucallback.v1.UniversalRead.request": + m := new(ReadRequest) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "ucallback.v1.UniversalRead.result": + m := new(ReadResult) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "ucallback.v1.UniversalRead.status": + return protoreflect.ValueOfEnum(0) + case "ucallback.v1.UniversalRead.ballot_key": + return protoreflect.ValueOfString("") + case "ucallback.v1.UniversalRead.pc_tx": + list := []*v1.PCTx{} + return protoreflect.ValueOfList(&_UniversalRead_6_list{list: &list}) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: ucallback.v1.UniversalRead")) + } + panic(fmt.Errorf("message ucallback.v1.UniversalRead does not contain field %s", fd.FullName())) + } +} + +// WhichOneof reports which field within the oneof is populated, +// returning nil if none are populated. +// It panics if the oneof descriptor does not belong to this message. +func (x *fastReflection_UniversalRead) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in ucallback.v1.UniversalRead", d.FullName())) + } + panic("unreachable") +} + +// GetUnknown retrieves the entire list of unknown fields. +// The caller may only mutate the contents of the RawFields +// if the mutated bytes are stored back into the message with SetUnknown. +func (x *fastReflection_UniversalRead) GetUnknown() protoreflect.RawFields { + return x.unknownFields +} + +// SetUnknown stores an entire list of unknown fields. +// The raw fields must be syntactically valid according to the wire format. +// An implementation may panic if this is not the case. +// Once stored, the caller must not mutate the content of the RawFields. +// An empty RawFields may be passed to clear the fields. +// +// SetUnknown is a mutating operation and unsafe for concurrent use. +func (x *fastReflection_UniversalRead) SetUnknown(fields protoreflect.RawFields) { + x.unknownFields = fields +} + +// IsValid reports whether the message is valid. +// +// An invalid message is an empty, read-only value. +// +// An invalid message often corresponds to a nil pointer of the concrete +// message type, but the details are implementation dependent. +// Validity is not part of the protobuf data model, and may not +// be preserved in marshaling or other operations. +func (x *fastReflection_UniversalRead) IsValid() bool { + return x != nil +} + +// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations. +// This method may return nil. +// +// The returned methods type is identical to +// "google.golang.org/protobuf/runtime/protoiface".Methods. +// Consult the protoiface package documentation for details. +func (x *fastReflection_UniversalRead) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*UniversalRead) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Id) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Request != nil { + l = options.Size(x.Request) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Result != nil { + l = options.Size(x.Result) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Status != 0 { + n += 1 + runtime.Sov(uint64(x.Status)) + } + l = len(x.BallotKey) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if len(x.PcTx) > 0 { + for _, e := range x.PcTx { + l = options.Size(e) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.unknownFields != nil { + n += len(x.unknownFields) + } + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: n, + } + } + + marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) { + x := input.Message.Interface().(*UniversalRead) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if len(x.PcTx) > 0 { + for iNdEx := len(x.PcTx) - 1; iNdEx >= 0; iNdEx-- { + encoded, err := options.Marshal(x.PcTx[iNdEx]) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x32 + } + } + if len(x.BallotKey) > 0 { + i -= len(x.BallotKey) + copy(dAtA[i:], x.BallotKey) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.BallotKey))) + i-- + dAtA[i] = 0x2a + } + if x.Status != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.Status)) + i-- + dAtA[i] = 0x20 + } + if x.Result != nil { + encoded, err := options.Marshal(x.Result) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x1a + } + if x.Request != nil { + encoded, err := options.Marshal(x.Request) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if len(x.Id) > 0 { + i -= len(x.Id) + copy(dAtA[i:], x.Id) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Id))) + i-- + dAtA[i] = 0xa + } + if input.Buf != nil { + input.Buf = append(input.Buf, dAtA...) + } else { + input.Buf = dAtA + } + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { + x := input.Message.Interface().(*UniversalRead) + if x == nil { + return protoiface.UnmarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Flags: input.Flags, + }, nil + } + options := runtime.UnmarshalInputToOptions(input) + _ = options + dAtA := input.Buf + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: UniversalRead: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: UniversalRead: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Request == nil { + x.Request = &ReadRequest{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Request); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Result == nil { + x.Result = &ReadResult{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Result); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + x.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.Status |= UniversalReadStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field BallotKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.BallotKey = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PcTx", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.PcTx = append(x.PcTx, &v1.PCTx{}) + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.PcTx[len(x.PcTx)-1]); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: ucallback/v1/types.proto + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// ReadStatus is the outcome a universal validator observed for a read. +type ReadStatus int32 + +const ( + ReadStatus_READ_STATUS_UNSPECIFIED ReadStatus = 0 + ReadStatus_READ_STATUS_SUCCESS ReadStatus = 1 + ReadStatus_READ_STATUS_ERROR ReadStatus = 2 +) + +// Enum value maps for ReadStatus. +var ( + ReadStatus_name = map[int32]string{ + 0: "READ_STATUS_UNSPECIFIED", + 1: "READ_STATUS_SUCCESS", + 2: "READ_STATUS_ERROR", + } + ReadStatus_value = map[string]int32{ + "READ_STATUS_UNSPECIFIED": 0, + "READ_STATUS_SUCCESS": 1, + "READ_STATUS_ERROR": 2, + } +) + +func (x ReadStatus) Enum() *ReadStatus { + p := new(ReadStatus) + *p = x + return p +} + +func (x ReadStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ReadStatus) Descriptor() protoreflect.EnumDescriptor { + return file_ucallback_v1_types_proto_enumTypes[0].Descriptor() +} + +func (ReadStatus) Type() protoreflect.EnumType { + return &file_ucallback_v1_types_proto_enumTypes[0] +} + +func (x ReadStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ReadStatus.Descriptor instead. +func (ReadStatus) EnumDescriptor() ([]byte, []int) { + return file_ucallback_v1_types_proto_rawDescGZIP(), []int{0} +} + +// UniversalReadStatus is the lifecycle state of a read request on Push Chain. +type UniversalReadStatus int32 + +const ( + UniversalReadStatus_UNIVERSAL_READ_STATUS_UNSPECIFIED UniversalReadStatus = 0 + UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING UniversalReadStatus = 1 // ingested, awaiting votes + UniversalReadStatus_UNIVERSAL_READ_STATUS_VOTING UniversalReadStatus = 2 // at least one vote, no quorum yet + UniversalReadStatus_UNIVERSAL_READ_STATUS_FULFILLED UniversalReadStatus = 3 // callback dispatched successfully + UniversalReadStatus_UNIVERSAL_READ_STATUS_EXPIRED UniversalReadStatus = 4 // expireExternalRead submitted + UniversalReadStatus_UNIVERSAL_READ_STATUS_FAILED UniversalReadStatus = 5 // quorum reached but the callback reverted +) + +// Enum value maps for UniversalReadStatus. +var ( + UniversalReadStatus_name = map[int32]string{ + 0: "UNIVERSAL_READ_STATUS_UNSPECIFIED", + 1: "UNIVERSAL_READ_STATUS_PENDING", + 2: "UNIVERSAL_READ_STATUS_VOTING", + 3: "UNIVERSAL_READ_STATUS_FULFILLED", + 4: "UNIVERSAL_READ_STATUS_EXPIRED", + 5: "UNIVERSAL_READ_STATUS_FAILED", + } + UniversalReadStatus_value = map[string]int32{ + "UNIVERSAL_READ_STATUS_UNSPECIFIED": 0, + "UNIVERSAL_READ_STATUS_PENDING": 1, + "UNIVERSAL_READ_STATUS_VOTING": 2, + "UNIVERSAL_READ_STATUS_FULFILLED": 3, + "UNIVERSAL_READ_STATUS_EXPIRED": 4, + "UNIVERSAL_READ_STATUS_FAILED": 5, + } +) + +func (x UniversalReadStatus) Enum() *UniversalReadStatus { + p := new(UniversalReadStatus) + *p = x + return p +} + +func (x UniversalReadStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (UniversalReadStatus) Descriptor() protoreflect.EnumDescriptor { + return file_ucallback_v1_types_proto_enumTypes[1].Descriptor() +} + +func (UniversalReadStatus) Type() protoreflect.EnumType { + return &file_ucallback_v1_types_proto_enumTypes[1] +} + +func (x UniversalReadStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use UniversalReadStatus.Descriptor instead. +func (UniversalReadStatus) EnumDescriptor() ([]byte, []int) { + return file_ucallback_v1_types_proto_rawDescGZIP(), []int{1} +} + +// ReadRequest is one external read requested by an app on Push Chain. +// +// Every field is derived from the UniversalCallback.ReadRequested event, except +// created_at_height / requested_tx_hash / requested_log_index which come from the +// block the log was emitted in. +// +// NOTE: callbackGasLimit is deliberately absent. It is an argument to +// requestExternalReadSelf and is stored in the contract's _pending entry, but it is +// NOT emitted in ReadRequested. It has to be read back via getPendingRead(requestId) +// at fulfilment time, when the gas budget is actually needed. +type ReadRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` // uint256 requestId as 0x-prefixed hex + DestinationChain string `protobuf:"bytes,2,opt,name=destination_chain,json=destinationChain,proto3" json:"destination_chain,omitempty"` // CAIP-2, e.g. "eip155:1"; web2 uses "web2:https" + Owner []byte `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"` // 20-byte address or 32-byte pubkey + Query []byte `protobuf:"bytes,4,opt,name=query,proto3" json:"query,omitempty"` // chain-specific envelope, abi.encode(...) + MinConfirmations uint32 `protobuf:"varint,5,opt,name=min_confirmations,json=minConfirmations,proto3" json:"min_confirmations,omitempty"` // uint16 on the contract; proto3 has no uint16 + DestinationBlockHeight uint64 `protobuf:"varint,6,opt,name=destination_block_height,json=destinationBlockHeight,proto3" json:"destination_block_height,omitempty"` // height on the destination chain; unused for web2 + ExpiryBlockHeight uint64 `protobuf:"varint,7,opt,name=expiry_block_height,json=expiryBlockHeight,proto3" json:"expiry_block_height,omitempty"` // Push Chain height at which the request expires + CreatedAtHeight uint64 `protobuf:"varint,8,opt,name=created_at_height,json=createdAtHeight,proto3" json:"created_at_height,omitempty"` // Push Chain height the request was observed at + // Bookkeeping — recorded for operators, not consumed by universal validators. + CallbackTarget string `protobuf:"bytes,9,opt,name=callback_target,json=callbackTarget,proto3" json:"callback_target,omitempty"` // the app contract the callback routes to + OriginalFunder string `protobuf:"bytes,10,opt,name=original_funder,json=originalFunder,proto3" json:"original_funder,omitempty"` // who paid the fee (the app, not the end user) + FeesDeposited string `protobuf:"bytes,11,opt,name=fees_deposited,json=feesDeposited,proto3" json:"fees_deposited,omitempty"` // uint256 as a decimal string + MaxFee string `protobuf:"bytes,12,opt,name=max_fee,json=maxFee,proto3" json:"max_fee,omitempty"` // uint256 as a decimal string + RequestedTxHash string `protobuf:"bytes,13,opt,name=requested_tx_hash,json=requestedTxHash,proto3" json:"requested_tx_hash,omitempty"` // Push Chain tx that emitted ReadRequested + RequestedLogIndex uint64 `protobuf:"varint,14,opt,name=requested_log_index,json=requestedLogIndex,proto3" json:"requested_log_index,omitempty"` // log index within that tx +} + +func (x *ReadRequest) Reset() { + *x = ReadRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_types_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadRequest) ProtoMessage() {} + +// Deprecated: Use ReadRequest.ProtoReflect.Descriptor instead. +func (*ReadRequest) Descriptor() ([]byte, []int) { + return file_ucallback_v1_types_proto_rawDescGZIP(), []int{0} +} + +func (x *ReadRequest) GetRequestId() string { + if x != nil { + return x.RequestId + } + return "" +} + +func (x *ReadRequest) GetDestinationChain() string { + if x != nil { + return x.DestinationChain + } + return "" +} + +func (x *ReadRequest) GetOwner() []byte { + if x != nil { + return x.Owner + } + return nil +} + +func (x *ReadRequest) GetQuery() []byte { + if x != nil { + return x.Query + } + return nil +} + +func (x *ReadRequest) GetMinConfirmations() uint32 { + if x != nil { + return x.MinConfirmations + } + return 0 +} + +func (x *ReadRequest) GetDestinationBlockHeight() uint64 { + if x != nil { + return x.DestinationBlockHeight + } + return 0 +} + +func (x *ReadRequest) GetExpiryBlockHeight() uint64 { + if x != nil { + return x.ExpiryBlockHeight + } + return 0 +} + +func (x *ReadRequest) GetCreatedAtHeight() uint64 { + if x != nil { + return x.CreatedAtHeight + } + return 0 +} + +func (x *ReadRequest) GetCallbackTarget() string { + if x != nil { + return x.CallbackTarget + } + return "" +} + +func (x *ReadRequest) GetOriginalFunder() string { + if x != nil { + return x.OriginalFunder + } + return "" +} + +func (x *ReadRequest) GetFeesDeposited() string { + if x != nil { + return x.FeesDeposited + } + return "" +} + +func (x *ReadRequest) GetMaxFee() string { + if x != nil { + return x.MaxFee + } + return "" +} + +func (x *ReadRequest) GetRequestedTxHash() string { + if x != nil { + return x.RequestedTxHash + } + return "" +} + +func (x *ReadRequest) GetRequestedLogIndex() uint64 { + if x != nil { + return x.RequestedLogIndex + } + return 0 +} + +// ReadResult is the observation a universal validator votes on. +// +// Fields 1-4 are covered by the ballot key, so they must be byte-identical across +// validators for a ballot to converge. There is deliberately no error message field: +// local error text differs per node and would prevent agreement. +type ReadResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status ReadStatus `protobuf:"varint,1,opt,name=status,proto3,enum=ucallback.v1.ReadStatus" json:"status,omitempty"` + ResultData []byte `protobuf:"bytes,2,opt,name=result_data,json=resultData,proto3" json:"result_data,omitempty"` // ABI-encoded payload delivered to the app + ObservedBlockHeight uint64 `protobuf:"varint,3,opt,name=observed_block_height,json=observedBlockHeight,proto3" json:"observed_block_height,omitempty"` // block number (EVM) or slot (SVM); 0 for web2 + ObservedBlockHash []byte `protobuf:"bytes,4,opt,name=observed_block_hash,json=observedBlockHash,proto3" json:"observed_block_hash,omitempty"` // 32 bytes; empty when the chain cannot pin one + // v2 ONLY — always empty in v1. See AggregateValue. + Aggregates []*AggregateValue `protobuf:"bytes,5,rep,name=aggregates,proto3" json:"aggregates,omitempty"` +} + +func (x *ReadResult) Reset() { + *x = ReadResult{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_types_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReadResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReadResult) ProtoMessage() {} + +// Deprecated: Use ReadResult.ProtoReflect.Descriptor instead. +func (*ReadResult) Descriptor() ([]byte, []int) { + return file_ucallback_v1_types_proto_rawDescGZIP(), []int{1} +} + +func (x *ReadResult) GetStatus() ReadStatus { + if x != nil { + return x.Status + } + return ReadStatus_READ_STATUS_UNSPECIFIED +} + +func (x *ReadResult) GetResultData() []byte { + if x != nil { + return x.ResultData + } + return nil +} + +func (x *ReadResult) GetObservedBlockHeight() uint64 { + if x != nil { + return x.ObservedBlockHeight + } + return 0 +} + +func (x *ReadResult) GetObservedBlockHash() []byte { + if x != nil { + return x.ObservedBlockHash + } + return nil +} + +func (x *ReadResult) GetAggregates() []*AggregateValue { + if x != nil { + return x.Aggregates + } + return nil +} + +// AggregateValue is one field the module combines across validators instead of +// requiring byte-equality on — a price, say, where honest nodes legitimately differ. +// +// NOT USED IN v1. The universal client rejects any extract mode other than IDENTICAL +// (externalchains/web2/read_envelope.go), so this list is always empty today. The field +// is reserved now because adding it later would change how ballots are keyed on a live +// chain, which is consensus-breaking. In v1 the ballot key covers all of fields 1-4; in +// v2 it must cover only fields 1-4 with `aggregates` EXCLUDED, so computing the key over +// "the identical subset" from the start keeps v2 purely additive. +// +// v2 ALSO REQUIRES REPLACING THE BALLOT MECHANISM, not just populating this field. +// Ballots today store a binary VoteResult{SUCCESS|FAILURE} against an ID that encodes the +// observation, so distinct observations produce distinct ballots and none reaches quorum +// when validators report different numbers. Ballots therefore cannot retain per-validator +// values, which is exactly what a median needs. v2 has to keep each validator's +// AggregateValue set in module state and reduce at quorum — the pattern x/uexecutor +// already uses for gas-price medians in keeper/chain_meta.go, which bypasses ballots for +// the same reason. +type AggregateValue struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExtractIndex uint32 `protobuf:"varint,1,opt,name=extract_index,json=extractIndex,proto3" json:"extract_index,omitempty"` // index into the query envelope's extract list + Mode uint32 `protobuf:"varint,2,opt,name=mode,proto3" json:"mode,omitempty"` // aggregation mode; only MEDIAN is planned + Value []byte `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` // big-endian uint256/int256 +} + +func (x *AggregateValue) Reset() { + *x = AggregateValue{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_types_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AggregateValue) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AggregateValue) ProtoMessage() {} + +// Deprecated: Use AggregateValue.ProtoReflect.Descriptor instead. +func (*AggregateValue) Descriptor() ([]byte, []int) { + return file_ucallback_v1_types_proto_rawDescGZIP(), []int{2} +} + +func (x *AggregateValue) GetExtractIndex() uint32 { + if x != nil { + return x.ExtractIndex + } + return 0 +} + +func (x *AggregateValue) GetMode() uint32 { + if x != nil { + return x.Mode + } + return 0 +} + +func (x *AggregateValue) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +// UniversalRead is the full lifecycle record of one read request. +// +// The read-side sibling of uexecutor's UniversalTx, but deliberately not the same +// shape: a read is triggered by a Push Chain event rather than an external inbound, +// performs no external write, and settles in exactly one Push Chain transaction. +type UniversalRead struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // requestId, same value as request.request_id + Request *ReadRequest `protobuf:"bytes,2,opt,name=request,proto3" json:"request,omitempty"` + Result *ReadResult `protobuf:"bytes,3,opt,name=result,proto3" json:"result,omitempty"` // set once the ballot finalises + Status UniversalReadStatus `protobuf:"varint,4,opt,name=status,proto3,enum=ucallback.v1.UniversalReadStatus" json:"status,omitempty"` + BallotKey string `protobuf:"bytes,5,opt,name=ballot_key,json=ballotKey,proto3" json:"ballot_key,omitempty"` + // Push Chain execution attempts — fulfilExternalCallback and expireExternalRead. + // Repeated because fulfilment can be retried and may be followed by an expiry. + PcTx []*v1.PCTx `protobuf:"bytes,6,rep,name=pc_tx,json=pcTx,proto3" json:"pc_tx,omitempty"` +} + +func (x *UniversalRead) Reset() { + *x = UniversalRead{} + if protoimpl.UnsafeEnabled { + mi := &file_ucallback_v1_types_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UniversalRead) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UniversalRead) ProtoMessage() {} + +// Deprecated: Use UniversalRead.ProtoReflect.Descriptor instead. +func (*UniversalRead) Descriptor() ([]byte, []int) { + return file_ucallback_v1_types_proto_rawDescGZIP(), []int{3} +} + +func (x *UniversalRead) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *UniversalRead) GetRequest() *ReadRequest { + if x != nil { + return x.Request + } + return nil +} + +func (x *UniversalRead) GetResult() *ReadResult { + if x != nil { + return x.Result + } + return nil +} + +func (x *UniversalRead) GetStatus() UniversalReadStatus { + if x != nil { + return x.Status + } + return UniversalReadStatus_UNIVERSAL_READ_STATUS_UNSPECIFIED +} + +func (x *UniversalRead) GetBallotKey() string { + if x != nil { + return x.BallotKey + } + return "" +} + +func (x *UniversalRead) GetPcTx() []*v1.PCTx { + if x != nil { + return x.PcTx + } + return nil +} + +var File_ucallback_v1_types_proto protoreflect.FileDescriptor + +var file_ucallback_v1_types_proto_rawDesc = []byte{ + 0x0a, 0x18, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x31, 0x2f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x75, 0x63, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, + 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x18, 0x75, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2f, 0x76, 0x31, 0x2f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbc, 0x04, 0x0a, 0x0b, + 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, + 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x12, 0x2b, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, + 0x6d, 0x69, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x38, 0x0a, 0x18, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x16, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x78, + 0x70, 0x69, 0x72, 0x79, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, + 0x63, 0x6b, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, + 0x27, 0x0a, 0x0f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x75, 0x6e, 0x64, + 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, + 0x61, 0x6c, 0x46, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x66, 0x65, 0x65, 0x73, + 0x5f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x66, 0x65, 0x65, 0x73, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x64, 0x12, + 0x17, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x6d, 0x61, 0x78, 0x46, 0x65, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0d, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x54, 0x78, + 0x48, 0x61, 0x73, 0x68, 0x12, 0x2e, 0x0a, 0x13, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, + 0x64, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0e, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x11, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4c, 0x6f, 0x67, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, 0x87, 0x02, 0x0a, 0x0a, 0x52, + 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x30, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x75, 0x63, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0a, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x15, + 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x6f, 0x62, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x12, 0x2e, 0x0a, 0x13, 0x6f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x6f, + 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, + 0x12, 0x3c, 0x0a, 0x0a, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x0a, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x73, 0x3a, 0x04, + 0xe8, 0xa0, 0x1f, 0x01, 0x22, 0x65, 0x0a, 0x0e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x65, + 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x6d, + 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x04, 0xe8, 0xa0, 0x1f, 0x01, 0x22, 0xac, 0x02, 0x0a, 0x0d, + 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x33, 0x0a, + 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x30, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, + 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x52, 0x65, 0x61, + 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x6c, 0x6c, 0x6f, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x61, 0x6c, 0x6c, 0x6f, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x27, + 0x0a, 0x05, 0x70, 0x63, 0x5f, 0x74, 0x78, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x75, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x43, 0x54, + 0x78, 0x52, 0x04, 0x70, 0x63, 0x54, 0x78, 0x3a, 0x21, 0xe8, 0xa0, 0x1f, 0x01, 0x8a, 0xe7, 0xb0, + 0x2a, 0x18, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x75, 0x6e, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x2a, 0x5f, 0x0a, 0x0a, 0x52, 0x65, + 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x41, 0x44, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x55, 0x53, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x15, + 0x0a, 0x11, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x10, 0x02, 0x1a, 0x04, 0xa8, 0xa4, 0x1e, 0x01, 0x2a, 0xf1, 0x01, 0x0a, 0x13, + 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x52, 0x65, 0x61, 0x64, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x25, 0x0a, 0x21, 0x55, 0x4e, 0x49, 0x56, 0x45, 0x52, 0x53, 0x41, 0x4c, + 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x21, 0x0a, 0x1d, 0x55, 0x4e, + 0x49, 0x56, 0x45, 0x52, 0x53, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x20, 0x0a, + 0x1c, 0x55, 0x4e, 0x49, 0x56, 0x45, 0x52, 0x53, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, + 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x56, 0x4f, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, + 0x23, 0x0a, 0x1f, 0x55, 0x4e, 0x49, 0x56, 0x45, 0x52, 0x53, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x41, + 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x46, 0x55, 0x4c, 0x46, 0x49, 0x4c, 0x4c, + 0x45, 0x44, 0x10, 0x03, 0x12, 0x21, 0x0a, 0x1d, 0x55, 0x4e, 0x49, 0x56, 0x45, 0x52, 0x53, 0x41, + 0x4c, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x58, + 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x04, 0x12, 0x20, 0x0a, 0x1c, 0x55, 0x4e, 0x49, 0x56, 0x45, + 0x52, 0x53, 0x41, 0x4c, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x1a, 0x04, 0xa8, 0xa4, 0x1e, 0x01, 0x42, + 0xb2, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, + 0x6b, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x54, 0x79, 0x70, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, + 0x75, 0x73, 0x68, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x75, 0x63, 0x61, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x63, 0x61, 0x6c, 0x6c, 0x62, + 0x61, 0x63, 0x6b, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x55, 0x58, 0x58, 0xaa, 0x02, 0x0c, 0x55, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0c, 0x55, 0x63, 0x61, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x18, 0x55, 0x63, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0d, 0x55, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, + 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_ucallback_v1_types_proto_rawDescOnce sync.Once + file_ucallback_v1_types_proto_rawDescData = file_ucallback_v1_types_proto_rawDesc +) + +func file_ucallback_v1_types_proto_rawDescGZIP() []byte { + file_ucallback_v1_types_proto_rawDescOnce.Do(func() { + file_ucallback_v1_types_proto_rawDescData = protoimpl.X.CompressGZIP(file_ucallback_v1_types_proto_rawDescData) + }) + return file_ucallback_v1_types_proto_rawDescData +} + +var file_ucallback_v1_types_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_ucallback_v1_types_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_ucallback_v1_types_proto_goTypes = []interface{}{ + (ReadStatus)(0), // 0: ucallback.v1.ReadStatus + (UniversalReadStatus)(0), // 1: ucallback.v1.UniversalReadStatus + (*ReadRequest)(nil), // 2: ucallback.v1.ReadRequest + (*ReadResult)(nil), // 3: ucallback.v1.ReadResult + (*AggregateValue)(nil), // 4: ucallback.v1.AggregateValue + (*UniversalRead)(nil), // 5: ucallback.v1.UniversalRead + (*v1.PCTx)(nil), // 6: uexecutor.v1.PCTx +} +var file_ucallback_v1_types_proto_depIdxs = []int32{ + 0, // 0: ucallback.v1.ReadResult.status:type_name -> ucallback.v1.ReadStatus + 4, // 1: ucallback.v1.ReadResult.aggregates:type_name -> ucallback.v1.AggregateValue + 2, // 2: ucallback.v1.UniversalRead.request:type_name -> ucallback.v1.ReadRequest + 3, // 3: ucallback.v1.UniversalRead.result:type_name -> ucallback.v1.ReadResult + 1, // 4: ucallback.v1.UniversalRead.status:type_name -> ucallback.v1.UniversalReadStatus + 6, // 5: ucallback.v1.UniversalRead.pc_tx:type_name -> uexecutor.v1.PCTx + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name +} + +func init() { file_ucallback_v1_types_proto_init() } +func file_ucallback_v1_types_proto_init() { + if File_ucallback_v1_types_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_ucallback_v1_types_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_types_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReadResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_types_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AggregateValue); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ucallback_v1_types_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UniversalRead); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_ucallback_v1_types_proto_rawDesc, + NumEnums: 2, + NumMessages: 4, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_ucallback_v1_types_proto_goTypes, + DependencyIndexes: file_ucallback_v1_types_proto_depIdxs, + EnumInfos: file_ucallback_v1_types_proto_enumTypes, + MessageInfos: file_ucallback_v1_types_proto_msgTypes, + }.Build() + File_ucallback_v1_types_proto = out.File + file_ucallback_v1_types_proto_rawDesc = nil + file_ucallback_v1_types_proto_goTypes = nil + file_ucallback_v1_types_proto_depIdxs = nil +} diff --git a/api/uvalidator/v1/ballot.pulsar.go b/api/uvalidator/v1/ballot.pulsar.go index 7cff2556..295b5dd8 100644 --- a/api/uvalidator/v1/ballot.pulsar.go +++ b/api/uvalidator/v1/ballot.pulsar.go @@ -1054,6 +1054,7 @@ const ( BallotObservationType_BALLOT_OBSERVATION_TYPE_OUTBOUND_TX BallotObservationType = 2 BallotObservationType_BALLOT_OBSERVATION_TYPE_TSS_KEY BallotObservationType = 3 BallotObservationType_BALLOT_OBSERVATION_TYPE_FUND_MIGRATION BallotObservationType = 4 + BallotObservationType_BALLOT_OBSERVATION_TYPE_READ_RESULT BallotObservationType = 5 ) // Enum value maps for BallotObservationType. @@ -1064,6 +1065,7 @@ var ( 2: "BALLOT_OBSERVATION_TYPE_OUTBOUND_TX", 3: "BALLOT_OBSERVATION_TYPE_TSS_KEY", 4: "BALLOT_OBSERVATION_TYPE_FUND_MIGRATION", + 5: "BALLOT_OBSERVATION_TYPE_READ_RESULT", } BallotObservationType_value = map[string]int32{ "BALLOT_OBSERVATION_TYPE_UNSPECIFIED": 0, @@ -1071,6 +1073,7 @@ var ( "BALLOT_OBSERVATION_TYPE_OUTBOUND_TX": 2, "BALLOT_OBSERVATION_TYPE_TSS_KEY": 3, "BALLOT_OBSERVATION_TYPE_FUND_MIGRATION": 4, + "BALLOT_OBSERVATION_TYPE_READ_RESULT": 5, } ) @@ -1289,7 +1292,7 @@ var file_uvalidator_v1_ballot_proto_rawDesc = []byte{ 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x19, 0x0a, 0x15, 0x42, 0x41, 0x4c, 0x4c, 0x4f, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x04, 0x1a, 0x04, - 0xa8, 0xa4, 0x1e, 0x01, 0x2a, 0xe8, 0x01, 0x0a, 0x15, 0x42, 0x61, 0x6c, 0x6c, 0x6f, 0x74, 0x4f, + 0xa8, 0xa4, 0x1e, 0x01, 0x2a, 0x91, 0x02, 0x0a, 0x15, 0x42, 0x61, 0x6c, 0x6c, 0x6f, 0x74, 0x4f, 0x62, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x27, 0x0a, 0x23, 0x42, 0x41, 0x4c, 0x4c, 0x4f, 0x54, 0x5f, 0x4f, 0x42, 0x53, 0x45, 0x52, 0x56, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, @@ -1303,26 +1306,29 @@ var file_uvalidator_v1_ballot_proto_rawDesc = []byte{ 0x59, 0x50, 0x45, 0x5f, 0x54, 0x53, 0x53, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x03, 0x12, 0x2a, 0x0a, 0x26, 0x42, 0x41, 0x4c, 0x4c, 0x4f, 0x54, 0x5f, 0x4f, 0x42, 0x53, 0x45, 0x52, 0x56, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x55, 0x4e, 0x44, 0x5f, 0x4d, 0x49, - 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x1a, 0x04, 0xa8, 0xa4, 0x1e, 0x01, 0x2a, - 0x63, 0x0a, 0x0a, 0x56, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1d, 0x0a, - 0x19, 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x4e, 0x4f, 0x54, - 0x5f, 0x59, 0x45, 0x54, 0x5f, 0x56, 0x4f, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, - 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x53, 0x55, 0x43, 0x43, - 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x52, 0x45, - 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x02, 0x1a, 0x04, - 0xa8, 0xa4, 0x1e, 0x01, 0x42, 0xba, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x75, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x42, 0x61, 0x6c, 0x6c, - 0x6f, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x75, 0x73, 0x68, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, - 0x70, 0x75, 0x73, 0x68, 0x2d, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, - 0x61, 0x70, 0x69, 0x2f, 0x75, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x76, - 0x31, 0x3b, 0x75, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x76, 0x31, 0xa2, 0x02, - 0x03, 0x55, 0x58, 0x58, 0xaa, 0x02, 0x0d, 0x55, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0d, 0x55, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x19, 0x55, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x0e, 0x55, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x3a, 0x3a, 0x56, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x04, 0x12, 0x27, 0x0a, 0x23, 0x42, 0x41, 0x4c, + 0x4c, 0x4f, 0x54, 0x5f, 0x4f, 0x42, 0x53, 0x45, 0x52, 0x56, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, + 0x10, 0x05, 0x1a, 0x04, 0xa8, 0xa4, 0x1e, 0x01, 0x2a, 0x63, 0x0a, 0x0a, 0x56, 0x6f, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1d, 0x0a, 0x19, 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x52, + 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x59, 0x45, 0x54, 0x5f, 0x56, 0x4f, + 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x52, 0x45, + 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x17, + 0x0a, 0x13, 0x56, 0x4f, 0x54, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x46, 0x41, + 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x02, 0x1a, 0x04, 0xa8, 0xa4, 0x1e, 0x01, 0x42, 0xba, 0x01, + 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x75, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x42, 0x61, 0x6c, 0x6c, 0x6f, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, + 0x75, 0x73, 0x68, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x75, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x55, 0x58, 0x58, 0xaa, 0x02, 0x0d, + 0x55, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0d, + 0x55, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x19, + 0x55, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x55, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( diff --git a/app/app.go b/app/app.go index 2d0d904d..120d350c 100644 --- a/app/app.go +++ b/app/app.go @@ -10,7 +10,6 @@ import ( "sort" "sync" "time" - autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" "cosmossdk.io/client/v2/autocli" @@ -119,7 +118,6 @@ import ( feemarketkeeper "github.com/cosmos/evm/x/feemarket/keeper" feemarkettypes "github.com/cosmos/evm/x/feemarket/types" "github.com/cosmos/evm/x/vm" - // _ "github.com/ethereum/go-ethereum/core/tracers/js" // _ "github.com/ethereum/go-ethereum/core/tracers/native" evmkeeper "github.com/cosmos/evm/x/vm/keeper" @@ -153,12 +151,10 @@ import ( ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v10/modules/core/keeper" ibctm "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" - // "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/common" cosmoscorevm "github.com/ethereum/go-ethereum/core/vm" chainante "github.com/pushchain/push-chain-node/app/ante" - usigverifierprecompile "github.com/pushchain/push-chain-node/precompiles/usigverifier" pushtypes "github.com/pushchain/push-chain-node/types" uexecutor "github.com/pushchain/push-chain-node/x/uexecutor" @@ -178,8 +174,10 @@ import ( tokenfactorybindings "github.com/strangelove-ventures/tokenfactory/x/tokenfactory/bindings" tokenfactorykeeper "github.com/strangelove-ventures/tokenfactory/x/tokenfactory/keeper" tokenfactorytypes "github.com/strangelove-ventures/tokenfactory/x/tokenfactory/types" - ibccallbacks "github.com/cosmos/ibc-go/v10/modules/apps/callbacks" + ucallback "github.com/pushchain/push-chain-node/x/ucallback" + ucallbackkeeper "github.com/pushchain/push-chain-node/x/ucallback/keeper" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" ) const ( @@ -337,6 +335,7 @@ type ChainApp struct { UregistryKeeper uregistrykeeper.Keeper UvalidatorKeeper uvalidatorkeeper.Keeper UtssKeeper utsskeeper.Keeper + UcallbackKeeper ucallbackkeeper.Keeper // the module manager ModuleManager *module.Manager @@ -451,6 +450,7 @@ func NewChainApp( uregistrytypes.StoreKey, uvalidatortypes.StoreKey, utsstypes.StoreKey, + ucallbacktypes.StoreKey, ) tkeys := storetypes.NewTransientStoreKeys( @@ -684,6 +684,19 @@ func NewChainApp( // If evidence needs to be handled for the app, set routes in router here and seal app.EvidenceKeeper = *evidenceKeeper + // Create the ucallback Keeper. + // + // UvalidatorKeeper is constructed further down, so this takes a pointer to the + // field rather than its value — same pattern as UexecutorKeeper below. The + // pointer is stable; the value it refers to is populated before any tx runs. + app.UcallbackKeeper = ucallbackkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[ucallbacktypes.StoreKey]), + logger, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + &app.UvalidatorKeeper, + ) + app.FeeMarketKeeper = feemarketkeeper.NewKeeper( appCodec, authtypes.NewModuleAddress(govtypes.ModuleName), @@ -791,7 +804,13 @@ func NewChainApp( ), ) - app.EVMKeeper.SetHooks(uexecutorkeeper.NewEVMHooks(app.UexecutorKeeper)) + // SetHooks panics if called twice, so every EVM post-tx consumer registers + // here. Hooks run in order and share a transaction: an error from any one of + // them reverts the whole EVM tx, including the work earlier hooks did. + app.EVMKeeper.SetHooks(evmkeeper.NewMultiEvmHooks( + uexecutorkeeper.NewEVMHooks(app.UexecutorKeeper), + ucallbackkeeper.NewEVMHooks(app.UcallbackKeeper), + )) // NOTE: we are adding all available EVM extensions. // Not all of them need to be enabled, which can be configured on a per-chain basis. @@ -1061,6 +1080,8 @@ func NewChainApp( uregistry.NewAppModule(appCodec, app.UregistryKeeper, app.EVMKeeper), uvalidator.NewAppModule(appCodec, app.UvalidatorKeeper, app.BankKeeper, app.AccountKeeper, app.DistrKeeper, app.StakingKeeper, app.SlashingKeeper, &app.UtssKeeper), utss.NewAppModule(appCodec, app.UtssKeeper, app.UvalidatorKeeper), + ucallback.NewAppModule(appCodec, app.UcallbackKeeper), + ) // BasicModuleManager defines the module BasicManager is in charge of setting up basic, @@ -1111,6 +1132,7 @@ func NewChainApp( uexecutortypes.ModuleName, uregistrytypes.ModuleName, utsstypes.ModuleName, + ucallbacktypes.ModuleName, ) app.ModuleManager.SetOrderEndBlockers( @@ -1134,6 +1156,7 @@ func NewChainApp( uregistrytypes.ModuleName, uvalidatortypes.ModuleName, utsstypes.ModuleName, + ucallbacktypes.ModuleName, ) // NOTE: The genutils module must occur after staking so that pools are @@ -1184,6 +1207,7 @@ func NewChainApp( uregistrytypes.ModuleName, uvalidatortypes.ModuleName, utsstypes.ModuleName, + ucallbacktypes.ModuleName, } app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...) app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...) @@ -1663,6 +1687,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(uregistrytypes.ModuleName) paramsKeeper.Subspace(uvalidatortypes.ModuleName) paramsKeeper.Subspace(utsstypes.ModuleName) + paramsKeeper.Subspace(ucallbacktypes.ModuleName) return paramsKeeper } diff --git a/proto/ucallback/module/v1/module.proto b/proto/ucallback/module/v1/module.proto new file mode 100755 index 00000000..09ef40ac --- /dev/null +++ b/proto/ucallback/module/v1/module.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package ucallback.module.v1; + +import "cosmos/app/v1alpha1/module.proto"; + +// Module is the app config object of the module. +// Learn more: https://docs.cosmos.network/main/building-modules/depinject +message Module { + option (cosmos.app.v1alpha1.module) = { + go_import : "github.com/pushchain/push-chain-node" + }; +} \ No newline at end of file diff --git a/proto/ucallback/v1/genesis.proto b/proto/ucallback/v1/genesis.proto new file mode 100755 index 00000000..c8afff27 --- /dev/null +++ b/proto/ucallback/v1/genesis.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; +package ucallback.v1; + +import "gogoproto/gogo.proto"; +import "amino/amino.proto"; +import "ucallback/v1/types.proto"; + +option go_package = "github.com/pushchain/push-chain-node/x/ucallback/types"; + +// GenesisState defines the module genesis state +message GenesisState { + // Params defines all the parameters of the module. + Params params = 1 [(gogoproto.nullable) = false]; + + // universal_reads are key-value pairs from the UniversalReads map. + // + // Only the canonical records are exported. PendingByExpiry and ReadsByTxHash + // are indexes derived from these, and are rebuilt during InitGenesis rather + // than exported — so they cannot be imported out of sync with the records they + // point at. + repeated UniversalReadEntry universal_reads = 2 [(gogoproto.nullable) = false]; +} + +// UniversalReadEntry is one key-value pair from the UniversalReads map. +message UniversalReadEntry { + string key = 1; + UniversalRead value = 2 [(gogoproto.nullable) = false]; +} + +// Params defines the set of module parameters. +message Params { + option (amino.name) = "ucallback/params"; + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + bool some_value = 2; +} \ No newline at end of file diff --git a/proto/ucallback/v1/query.proto b/proto/ucallback/v1/query.proto new file mode 100755 index 00000000..318992d4 --- /dev/null +++ b/proto/ucallback/v1/query.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; +package ucallback.v1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ucallback/v1/genesis.proto"; +import "ucallback/v1/types.proto"; + +option go_package = "github.com/pushchain/push-chain-node/x/ucallback/types"; + +// Query provides defines the gRPC querier service. +service Query { + // Params queries all parameters of the module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/ucallback/v1/params"; + } + + // AllPendingReadRequests lists read requests still awaiting an observation. + // This is the endpoint universal validators poll. + rpc AllPendingReadRequests(QueryAllPendingReadRequestsRequest) returns (QueryAllPendingReadRequestsResponse) { + option (google.api.http).get = "/ucallback/v1/pending_read_requests"; + } + + // UniversalRead returns one read by request id, at any point in its lifecycle. + rpc UniversalRead(QueryUniversalReadRequest) returns (QueryUniversalReadResponse) { + option (google.api.http).get = "/ucallback/v1/universal_reads/{request_id}"; + } + + // ReadsByTxHash returns every read requested by one Push transaction. A single + // transaction can emit several ReadRequested logs; this reassembles that batch. + rpc ReadsByTx(QueryReadsByTxRequest) returns (QueryReadsByTxResponse) { + option (google.api.http).get = "/ucallback/v1/reads_by_tx/{tx_hash}"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params defines the parameters of the module. + Params params = 1; +} + +message QueryAllPendingReadRequestsRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +message QueryAllPendingReadRequestsResponse { + // Reads that are unsettled AND not yet past their expiry height. Requests past + // expiry are withheld here even before the sweeper retires them, so validators + // never take on work that can no longer be fulfilled in time. + repeated UniversalRead reads = 1 [(gogoproto.nullable) = false]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +message QueryUniversalReadRequest { + string request_id = 1; +} + +message QueryUniversalReadResponse { + UniversalRead read = 1 [(gogoproto.nullable) = false]; +} + +message QueryReadsByTxRequest { + string tx_hash = 1; +} + +message QueryReadsByTxResponse { + // Every read the transaction requested, settled or not, in request-id order. + repeated UniversalRead reads = 1 [(gogoproto.nullable) = false]; +} diff --git a/proto/ucallback/v1/tx.proto b/proto/ucallback/v1/tx.proto new file mode 100755 index 00000000..be9bfa5e --- /dev/null +++ b/proto/ucallback/v1/tx.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; +package ucallback.v1; + +import "cosmos/msg/v1/msg.proto"; +import "ucallback/v1/genesis.proto"; +import "ucallback/v1/types.proto"; +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "amino/amino.proto"; + +option go_package = "github.com/pushchain/push-chain-node/x/ucallback/types"; + +// Msg defines the Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // VoteReadResult submits one universal validator's observation of a read + // request's outcome on the destination chain. + rpc VoteReadResult(MsgVoteReadResult) returns (MsgVoteReadResultResponse); + + // UpdateParams defines a governance operation for updating the parameters. + // + // Since: cosmos-sdk 0.47 + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +// MsgUpdateParams is the Msg/UpdateParams request type. +// +// Since: cosmos-sdk 0.47 +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "authority"; + + // authority is the address of the governance account. + string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // params defines the parameters to update. + // + // NOTE: All parameters must be supplied. + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse defines the response structure for executing a +// MsgUpdateParams message. +// +// Since: cosmos-sdk 0.47 +message MsgUpdateParamsResponse {} + +// MsgVoteReadResult is broadcast by a universal validator that has executed a +// read request against the destination chain. +// +// The ballot the vote lands on is derived from (request_id, result), so two +// validators reporting the same observation converge on one ballot and any +// disagreement produces a distinct ballot that never reaches quorum. Nothing +// validator-local may appear in `result` for that reason — notably there is no +// error message field. +message MsgVoteReadResult { + option (amino.name) = "ucallback/MsgVoteReadResult"; + option (cosmos.msg.v1.signer) = "signer"; + + // signer is the Cosmos address of the voting universal validator. + string signer = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // request_id identifies the read request being voted on. + string request_id = 2; + + // result is the observation. Every field participates in the ballot key. + ReadResult result = 3; +} + +message MsgVoteReadResultResponse { + // finalized reports whether this vote carried the ballot to quorum. + bool finalized = 1; +} diff --git a/proto/ucallback/v1/types.proto b/proto/ucallback/v1/types.proto new file mode 100644 index 00000000..9c14a310 --- /dev/null +++ b/proto/ucallback/v1/types.proto @@ -0,0 +1,123 @@ +syntax = "proto3"; +package ucallback.v1; + +import "gogoproto/gogo.proto"; +import "amino/amino.proto"; +import "uexecutor/v1/types.proto"; + +option go_package = "github.com/pushchain/push-chain-node/x/ucallback/types"; + +// ReadStatus is the outcome a universal validator observed for a read. +enum ReadStatus { + option (gogoproto.goproto_enum_stringer) = true; + + READ_STATUS_UNSPECIFIED = 0; + READ_STATUS_SUCCESS = 1; + READ_STATUS_ERROR = 2; +} + +// UniversalReadStatus is the lifecycle state of a read request on Push Chain. +enum UniversalReadStatus { + option (gogoproto.goproto_enum_stringer) = true; + + UNIVERSAL_READ_STATUS_UNSPECIFIED = 0; + UNIVERSAL_READ_STATUS_PENDING = 1; // ingested, awaiting votes + UNIVERSAL_READ_STATUS_VOTING = 2; // at least one vote, no quorum yet + UNIVERSAL_READ_STATUS_FULFILLED = 3; // callback dispatched successfully + UNIVERSAL_READ_STATUS_EXPIRED = 4; // expireExternalRead submitted + UNIVERSAL_READ_STATUS_FAILED = 5; // quorum reached but the callback reverted +} + +// ReadRequest is one external read requested by an app on Push Chain. +// +// Every field is derived from the UniversalCallback.ReadRequested event, except +// created_at_height / requested_tx_hash / requested_log_index which come from the +// block the log was emitted in. +// +// NOTE: callbackGasLimit is deliberately absent. It is an argument to +// requestExternalReadSelf and is stored in the contract's _pending entry, but it is +// NOT emitted in ReadRequested. It has to be read back via getPendingRead(requestId) +// at fulfilment time, when the gas budget is actually needed. +message ReadRequest { + option (gogoproto.equal) = true; + + string request_id = 1; // uint256 requestId as 0x-prefixed hex + string destination_chain = 2; // CAIP-2, e.g. "eip155:1"; web2 uses "web2:https" + bytes owner = 3; // 20-byte address or 32-byte pubkey + bytes query = 4; // chain-specific envelope, abi.encode(...) + uint32 min_confirmations = 5; // uint16 on the contract; proto3 has no uint16 + uint64 destination_block_height = 6; // height on the destination chain; unused for web2 + uint64 expiry_block_height = 7; // Push Chain height at which the request expires + uint64 created_at_height = 8; // Push Chain height the request was observed at + + // Bookkeeping — recorded for operators, not consumed by universal validators. + string callback_target = 9; // the app contract the callback routes to + string original_funder = 10; // who paid the fee (the app, not the end user) + string fees_deposited = 11; // uint256 as a decimal string + string max_fee = 12; // uint256 as a decimal string + string requested_tx_hash = 13; // Push Chain tx that emitted ReadRequested + uint64 requested_log_index = 14; // log index within that tx +} + +// ReadResult is the observation a universal validator votes on. +// +// Fields 1-4 are covered by the ballot key, so they must be byte-identical across +// validators for a ballot to converge. There is deliberately no error message field: +// local error text differs per node and would prevent agreement. +message ReadResult { + option (gogoproto.equal) = true; + + ReadStatus status = 1; + bytes result_data = 2; // ABI-encoded payload delivered to the app + uint64 observed_block_height = 3; // block number (EVM) or slot (SVM); 0 for web2 + bytes observed_block_hash = 4; // 32 bytes; empty when the chain cannot pin one + + // v2 ONLY — always empty in v1. See AggregateValue. + repeated AggregateValue aggregates = 5; +} + +// AggregateValue is one field the module combines across validators instead of +// requiring byte-equality on — a price, say, where honest nodes legitimately differ. +// +// NOT USED IN v1. The universal client rejects any extract mode other than IDENTICAL +// (externalchains/web2/read_envelope.go), so this list is always empty today. The field +// is reserved now because adding it later would change how ballots are keyed on a live +// chain, which is consensus-breaking. In v1 the ballot key covers all of fields 1-4; in +// v2 it must cover only fields 1-4 with `aggregates` EXCLUDED, so computing the key over +// "the identical subset" from the start keeps v2 purely additive. +// +// v2 ALSO REQUIRES REPLACING THE BALLOT MECHANISM, not just populating this field. +// Ballots today store a binary VoteResult{SUCCESS|FAILURE} against an ID that encodes the +// observation, so distinct observations produce distinct ballots and none reaches quorum +// when validators report different numbers. Ballots therefore cannot retain per-validator +// values, which is exactly what a median needs. v2 has to keep each validator's +// AggregateValue set in module state and reduce at quorum — the pattern x/uexecutor +// already uses for gas-price medians in keeper/chain_meta.go, which bypasses ballots for +// the same reason. +message AggregateValue { + option (gogoproto.equal) = true; + + uint32 extract_index = 1; // index into the query envelope's extract list + uint32 mode = 2; // aggregation mode; only MEDIAN is planned + bytes value = 3; // big-endian uint256/int256 +} + +// UniversalRead is the full lifecycle record of one read request. +// +// The read-side sibling of uexecutor's UniversalTx, but deliberately not the same +// shape: a read is triggered by a Push Chain event rather than an external inbound, +// performs no external write, and settles in exactly one Push Chain transaction. +message UniversalRead { + option (amino.name) = "ucallback/universal_read"; + option (gogoproto.equal) = true; + + string id = 1; // requestId, same value as request.request_id + ReadRequest request = 2; + ReadResult result = 3; // set once the ballot finalises + UniversalReadStatus status = 4; + string ballot_key = 5; + + // Push Chain execution attempts — fulfilExternalCallback and expireExternalRead. + // Repeated because fulfilment can be retried and may be followed by an expiry. + repeated uexecutor.v1.PCTx pc_tx = 6; +} diff --git a/proto/uvalidator/v1/ballot.proto b/proto/uvalidator/v1/ballot.proto index d1353e9e..63ed6971 100644 --- a/proto/uvalidator/v1/ballot.proto +++ b/proto/uvalidator/v1/ballot.proto @@ -30,6 +30,7 @@ enum BallotObservationType { BALLOT_OBSERVATION_TYPE_OUTBOUND_TX = 2; BALLOT_OBSERVATION_TYPE_TSS_KEY = 3; BALLOT_OBSERVATION_TYPE_FUND_MIGRATION = 4; + BALLOT_OBSERVATION_TYPE_READ_RESULT = 5; } // --------------------------- diff --git a/scripts/protocgen.sh b/scripts/protocgen.sh index 551766d3..f7c0e512 100755 --- a/scripts/protocgen.sh +++ b/scripts/protocgen.sh @@ -28,7 +28,11 @@ rm -rf github.com # Copy files over for dep injection rm -rf api && mkdir api -custom_modules=$(find . -name 'module' -type d -not -path "./proto/*" -not -path "./.cache/*") +# NOTE: exclude ./compat/* — compat/orm-api/module is a vendored compatibility shim, not a +# generated proto module. Without this it is matched here, moved into ./api/ and then deleted by +# the `rm -rf $module` below, which breaks the `cosmossdk.io/api/cosmos/orm => ./compat/orm-api` +# replace in go.mod and fails the `go mod tidy` at the end of `make proto-gen`. +custom_modules=$(find . -name 'module' -type d -not -path "./proto/*" -not -path "./.cache/*" -not -path "./compat/*") # get the 1 up directory (so ./cosmos/mint/module becomes ./cosmos/mint) # remove the relative path starter from base namespaces. so ./cosmos/mint becomes cosmos/mint diff --git a/universalClient/core/client.go b/universalClient/core/client.go index 965e7c20..cf1cdb93 100644 --- a/universalClient/core/client.go +++ b/universalClient/core/client.go @@ -31,7 +31,7 @@ type UniversalClient struct { pushCore *pushcore.Client pushSigner *pushsigner.Signer chains *externalchains.Chains - pushChain *pushwatcher.Client + pushWatcher *pushwatcher.Client tssNode *tss.Node } @@ -70,21 +70,23 @@ func NewUniversalClient(ctx context.Context, cfg *config.Config) (*UniversalClie chainsManager := externalchains.NewChains(pushCore, pushSigner, cfg, log) - // Push chain DB is shared by the push chain client and the TSS node. + // Push chain DB is shared by the push watcher and the TSS node. pushDB, err := openPushDB(cfg) if err != nil { return nil, err } - pushChain, err := pushwatcher.NewClient( + pushWatcher, err := pushwatcher.NewClient( pushDB, cfg.GetChainConfig(cfg.PushChainID), pushCore, cfg.PushChainID, log, + pushSigner, + chainsManager, ) if err != nil { - return nil, fmt.Errorf("failed to create push chain client: %w", err) + return nil, fmt.Errorf("failed to create push watcher: %w", err) } tssNode, err := initTSS(ctx, cfg, pushCore, chainsManager, pushSigner, pushDB, log) @@ -102,7 +104,7 @@ func NewUniversalClient(ctx context.Context, cfg *config.Config) (*UniversalClie pushCore: pushCore, pushSigner: pushSigner, chains: chainsManager, - pushChain: pushChain, + pushWatcher: pushWatcher, tssNode: tssNode, }, nil } @@ -130,8 +132,8 @@ func (uc *UniversalClient) Start() error { return fmt.Errorf("failed to start chains manager: %w", err) } - if err := uc.pushChain.Start(uc.ctx); err != nil { - return fmt.Errorf("failed to start push chain client: %w", err) + if err := uc.pushWatcher.Start(uc.ctx); err != nil { + return fmt.Errorf("failed to start push watcher: %w", err) } if uc.tssNode != nil { @@ -166,9 +168,9 @@ func (uc *UniversalClient) shutdown() { } } - if uc.pushChain != nil { - if err := uc.pushChain.Stop(); err != nil { - uc.log.Error().Err(err).Str("subsystem", "push_chain").Msg("subsystem failed to stop") + if uc.pushWatcher != nil { + if err := uc.pushWatcher.Stop(); err != nil { + uc.log.Error().Err(err).Str("subsystem", "push_watcher").Msg("subsystem failed to stop") } } diff --git a/universalClient/externalchains/chains_test.go b/universalClient/externalchains/chains_test.go index 20ed9d84..9426e0a8 100644 --- a/universalClient/externalchains/chains_test.go +++ b/universalClient/externalchains/chains_test.go @@ -413,6 +413,9 @@ type mockChainClient struct { func (m *mockChainClient) Start(ctx context.Context) error { m.startCalled = true; return nil } func (m *mockChainClient) Stop() error { m.stopCalled = true; return m.stopErr } func (m *mockChainClient) IsHealthy() bool { return true } +func (m *mockChainClient) GetReadRequestHandler() (common.ReadRequestHandler, error) { + return nil, nil +} func (m *mockChainClient) GetTxBuilder() (common.TxBuilder, error) { return nil, nil } diff --git a/universalClient/externalchains/common/chain_store.go b/universalClient/externalchains/common/chain_store.go index b67bd1f8..b711087c 100644 --- a/universalClient/externalchains/common/chain_store.go +++ b/universalClient/externalchains/common/chain_store.go @@ -154,24 +154,6 @@ func (cs *ChainStore) UpdateStatusAndEventData(eventID, oldStatus, newStatus str return res.RowsAffected, nil } -// UpdateVoteTxHash updates the vote_tx_hash field for an event -func (cs *ChainStore) UpdateVoteTxHash(eventID string, voteTxHash string) error { - if cs.database == nil { - return fmt.Errorf("database is nil") - } - - result := cs.database.Client(). - Model(&store.Event{}). - Where("event_id = ?", eventID). - Update("vote_tx_hash", voteTxHash) - - if result.Error != nil { - return fmt.Errorf("failed to update vote_tx_hash: %w", result.Error) - } - - return nil -} - // DeleteTerminalEvents deletes events in terminal states (COMPLETED, REVERTED, EXPIRED) // that were updated before the given time func (cs *ChainStore) DeleteTerminalEvents(updatedBefore any) (int64, error) { diff --git a/universalClient/externalchains/common/chain_store_test.go b/universalClient/externalchains/common/chain_store_test.go index a3b80989..bc413cac 100644 --- a/universalClient/externalchains/common/chain_store_test.go +++ b/universalClient/externalchains/common/chain_store_test.go @@ -56,12 +56,6 @@ func TestChainStoreNilDatabase(t *testing.T) { assert.Contains(t, err.Error(), "database is nil") }) - t.Run("UpdateVoteTxHash returns error for nil database", func(t *testing.T) { - err := store.UpdateVoteTxHash("event-1", "0x123") - require.Error(t, err) - assert.Contains(t, err.Error(), "database is nil") - }) - t.Run("InsertEventIfNotExists returns error for nil database", func(t *testing.T) { inserted, err := store.InsertEventIfNotExists(nil) require.Error(t, err) @@ -222,23 +216,6 @@ func TestChainStore_UpdateStatusAndEventData(t *testing.T) { assert.Equal(t, int64(1), rows) } -func TestChainStore_UpdateVoteTxHash(t *testing.T) { - cs := newTestChainStore(t) - - event := &storemodels.Event{ - EventID: "evt-5", - BlockHeight: 50, - Type: storemodels.EventTypeOutbound, - ConfirmationType: storemodels.ConfirmationStandard, - Status: storemodels.StatusConfirmed, - } - _, err := cs.InsertEventIfNotExists(event) - require.NoError(t, err) - - err = cs.UpdateVoteTxHash("evt-5", "0xvotehash") - require.NoError(t, err) -} - func TestChainStore_GetPendingEventsLimit(t *testing.T) { cs := newTestChainStore(t) diff --git a/universalClient/externalchains/common/event_processor.go b/universalClient/externalchains/common/event_processor.go index 3625d306..280ccf40 100644 --- a/universalClient/externalchains/common/event_processor.go +++ b/universalClient/externalchains/common/event_processor.go @@ -3,54 +3,67 @@ package common import ( "context" "encoding/hex" - "encoding/json" "fmt" - "strconv" "strings" "sync" "time" "github.com/mr-tron/base58" "github.com/pushchain/push-chain-node/universalClient/db" - "github.com/pushchain/push-chain-node/universalClient/pushsigner" "github.com/pushchain/push-chain-node/universalClient/store" uexecutortypes "github.com/pushchain/push-chain-node/x/uexecutor/types" "github.com/rs/zerolog" ) -// EventProcessor processes events from the chain's database and votes on them +const eventProcessBatchSize = 1000 + +// VoteSigner is the subset of pushsigner.Signer used by the event processors. +// Defined here (consumer-side) so tests can provide mock implementations. +type VoteSigner interface { + VoteInbound(ctx context.Context, inbound *uexecutortypes.Inbound) (string, error) + VoteOutbound(ctx context.Context, txID string, utxID string, observation *uexecutortypes.OutboundObservation) (string, error) +} + +// EventHandler processes one CONFIRMED event of a registered type. +// Handlers own the event's status transitions; a returned error is logged and +// the event is retried next tick. +type EventHandler interface { + HandleEvent(ctx context.Context, event *store.Event) error +} + +// EventProcessor drains CONFIRMED events from the chain's database and +// dispatches them to the handler registered for their type. Event types +// without a handler are ignored. type EventProcessor struct { - signer *pushsigner.Signer - chainStore *ChainStore - logger zerolog.Logger - chainID string - inboundEnabled bool - outboundEnabled bool - running bool - stopCh chan struct{} - wg sync.WaitGroup + chainStore *ChainStore + handlers map[string]EventHandler + chainID string + logger zerolog.Logger + running bool + stopCh chan struct{} + wg sync.WaitGroup } -// NewEventProcessor creates a new event processor +// NewEventProcessor creates a new event processor. Register handlers before Start. func NewEventProcessor( - signer *pushsigner.Signer, database *db.DB, chainID string, - inboundEnabled bool, - outboundEnabled bool, logger zerolog.Logger, ) *EventProcessor { return &EventProcessor{ - signer: signer, - chainStore: NewChainStore(database), - chainID: chainID, - inboundEnabled: inboundEnabled, - outboundEnabled: outboundEnabled, - logger: logger.With().Str("component", "event_processor").Str("chain", chainID).Logger(), - stopCh: make(chan struct{}), + chainStore: NewChainStore(database), + handlers: make(map[string]EventHandler), + chainID: chainID, + logger: logger.With().Str("component", "event_processor").Str("chain", chainID).Logger(), + stopCh: make(chan struct{}), } } +// RegisterHandler registers a handler for an event type. Must be called before Start. +func (ep *EventProcessor) RegisterHandler(eventType string, handler EventHandler) { + ep.handlers[eventType] = handler +} + // Start begins processing events func (ep *EventProcessor) Start(ctx context.Context) error { if ep.running { @@ -103,7 +116,6 @@ func (ep *EventProcessor) processLoop(ctx context.Context) { ep.logger.Debug().Msg("stop signal received, stopping event processor") return case <-ticker.C: - // Fetch 1000 CONFIRMED events and process them if err := ep.processConfirmedEvents(ctx); err != nil { ep.logger.Error().Err(err).Msg("failed to process confirmed events") } @@ -111,123 +123,43 @@ func (ep *EventProcessor) processLoop(ctx context.Context) { } } -// processConfirmedEvents processes confirmed events (both inbound and outbound) +// processConfirmedEvents dispatches CONFIRMED events to their registered handlers. func (ep *EventProcessor) processConfirmedEvents(ctx context.Context) error { - events, err := ep.chainStore.GetConfirmedEvents(1000) + events, err := ep.chainStore.GetConfirmedEvents(eventProcessBatchSize) if err != nil { return fmt.Errorf("failed to get confirmed events: %w", err) } for _, event := range events { - if event.Type == store.EventTypeInbound { - if !ep.inboundEnabled { - ep.logger.Warn().Str("event_id", event.EventID).Msg("inbound disabled, skipping inbound event processing") - continue - } - if err := ep.processInboundEvent(ctx, &event); err != nil { - ep.logger.Error(). - Err(err). - Str("event_id", event.EventID). - Msg("failed to vote on inbound event") - continue - } - } else if event.Type == store.EventTypeOutbound { - if !ep.outboundEnabled { - ep.logger.Warn().Str("event_id", event.EventID).Msg("outbound disabled, skipping outbound event processing") - continue - } - if err := ep.processOutboundEvent(ctx, &event); err != nil { - ep.logger.Error(). - Err(err). - Str("event_id", event.EventID). - Msg("failed to vote on outbound event") - continue - } + handler, ok := ep.handlers[event.Type] + if !ok { + continue } - } - - return nil -} - -// processOutboundEvent processes an outbound event by voting on it -func (ep *EventProcessor) processOutboundEvent(ctx context.Context, event *store.Event) error { - ep.logger.Debug(). - Str("event_id", event.EventID). - Msg("processing outbound event") - - // Parse outbound event data once - outboundData, err := ep.parseOutboundEventData(event) - if err != nil { - return fmt.Errorf("failed to parse outbound event data: %w", err) - } - - txID := outboundData.TxID - utxID := outboundData.UniversalTxID - - // Build observation from parsed data - observation, err := ep.buildOutboundObservation(event, outboundData) - if err != nil { - return fmt.Errorf("failed to build outbound observation: %w", err) - } - - // Vote on outbound - voteTxHash, err := ep.signer.VoteOutbound(ctx, txID, utxID, observation) - if err != nil { - return fmt.Errorf("failed to vote on outbound: %w", err) - } - // Atomically record vote hash and flip status in one DB write - rowsAffected, err := ep.chainStore.UpdateStatusAndVoteTxHash(event.EventID, store.StatusConfirmed, store.StatusCompleted, voteTxHash) - if err != nil { - return fmt.Errorf("failed to update event status and vote_tx_hash: %w", err) - } - - if rowsAffected == 0 { - return nil // already completed by another validator + if err := handler.HandleEvent(ctx, &event); err != nil { + ep.logger.Error(). + Err(err). + Str("event_id", event.EventID). + Str("type", event.Type). + Msg("failed to process event") + } } - ep.logger.Info(). - Str("event_id", event.EventID). - Str("type", event.Type). - Str("vote_tx_hash", voteTxHash). - Msg("event marked as COMPLETED") - return nil } -// processInboundEvent processes an inbound event by voting on it and confirming it -func (ep *EventProcessor) processInboundEvent(ctx context.Context, event *store.Event) error { - ep.logger.Debug(). - Str("event_id", event.EventID). - Msg("processing inbound event") - - // Extract inbound data from event - inbound, err := ep.constructInbound(event) - if err != nil { - return fmt.Errorf("failed to construct inbound: %w", err) - } - - // Execute vote on blockchain - voteTxHash, err := ep.signer.VoteInbound(ctx, inbound) - if err != nil { - ep.logger.Error(). - Str("event_id", event.EventID). - Err(err). - Msg("failed to vote on event - keeping status for retry") - return err - } - - // Atomically record vote hash and flip status in one DB write - rowsAffected, err := ep.chainStore.UpdateStatusAndVoteTxHash(event.EventID, store.StatusConfirmed, store.StatusCompleted, voteTxHash) +// markEventCompleted atomically records the vote hash and flips CONFIRMED -> COMPLETED. +func markEventCompleted(chainStore *ChainStore, logger zerolog.Logger, event *store.Event, voteTxHash string) error { + rowsAffected, err := chainStore.UpdateStatusAndVoteTxHash(event.EventID, store.StatusConfirmed, store.StatusCompleted, voteTxHash) if err != nil { return fmt.Errorf("failed to update event status after successful vote: %w", err) } if rowsAffected == 0 { - return nil // already completed by another validator + return nil // already completed } - ep.logger.Info(). + logger.Info(). Str("event_id", event.EventID). Str("type", event.Type). Str("vote_tx_hash", voteTxHash). @@ -236,86 +168,25 @@ func (ep *EventProcessor) processInboundEvent(ctx context.Context, event *store. return nil } -// constructInbound creates an Inbound message from event data -func (ep *EventProcessor) constructInbound(event *store.Event) (*uexecutortypes.Inbound, error) { - var eventData UniversalTx - - if event == nil { - return nil, fmt.Errorf("event is nil") - } - - if event.EventData == nil { - return nil, fmt.Errorf("event data is missing for event_id: %s", event.EventID) - } - - if err := json.Unmarshal(event.EventData, &eventData); err != nil { - return nil, fmt.Errorf("failed to unmarshal event data: %w", err) - } - - // Map txType from eventData to proper enum value - txType := uexecutortypes.TxType_UNSPECIFIED_TX - switch eventData.TxType { - case 0: - txType = uexecutortypes.TxType_GAS - case 1: - txType = uexecutortypes.TxType_GAS_AND_PAYLOAD - case 2: - txType = uexecutortypes.TxType_FUNDS - case 3: - txType = uexecutortypes.TxType_FUNDS_AND_PAYLOAD - default: - txType = uexecutortypes.TxType_UNSPECIFIED_TX - } - - // Extract txHash from EventID (format: "txHash:logIndex") +// eventTxHash extracts the tx hash from an EventID (format: "txHash:logIndex" +// or "signature:logIndex"), converting base58 signatures to 0x-prefixed hex. +// Falls back to the raw value if conversion fails. +func eventTxHash(eventID string) string { txHash := "" - parts := strings.Split(event.EventID, ":") + parts := strings.Split(eventID, ":") if len(parts) > 0 { txHash = parts[0] } - // Convert txHash to hex format if it's in base58 - txHashHex, err := ep.base58ToHex(txHash) + txHashHex, err := base58ToHex(txHash) if err != nil { - ep.logger.Warn(). - Str("tx_hash", txHash). - Err(err). - Msg("failed to convert txHash to hex, using original value") - txHashHex = txHash - } - - inboundMsg := &uexecutortypes.Inbound{ - SourceChain: eventData.SourceChain, - TxHash: txHashHex, - Sender: eventData.Sender, - Recipient: eventData.Recipient, - Amount: eventData.Amount, - AssetAddr: eventData.Token, - LogIndex: strconv.FormatUint(uint64(eventData.LogIndex), 10), - TxType: txType, - IsCEA: eventData.FromCEA, - RawPayload: eventData.RawPayload, - } - - // Set revert instructions if revert fund recipient is present - if eventData.RevertFundRecipient != "" { - inboundMsg.RevertInstructions = &uexecutortypes.RevertInstructions{ - FundRecipient: eventData.RevertFundRecipient, - } - } - - // Use event's VerificationData if present, otherwise fall back to txHash - if eventData.VerificationData == "" || eventData.VerificationData == "0x" { - inboundMsg.VerificationData = txHashHex - } else { - inboundMsg.VerificationData = eventData.VerificationData + return txHash } - - return inboundMsg, nil + return txHashHex } // base58ToHex converts a base58 encoded string to hex format (0x...) -func (ep *EventProcessor) base58ToHex(base58Str string) (string, error) { +func base58ToHex(base58Str string) (string, error) { if base58Str == "" { return "0x", nil } @@ -334,65 +205,3 @@ func (ep *EventProcessor) base58ToHex(base58Str string) (string, error) { // Convert to hex with 0x prefix return "0x" + hex.EncodeToString(decoded), nil } - -// parseOutboundEventData unmarshals event data into an OutboundEvent struct -func (ep *EventProcessor) parseOutboundEventData(event *store.Event) (*OutboundEvent, error) { - if event == nil { - return nil, fmt.Errorf("event is nil") - } - - if len(event.EventData) == 0 { - return nil, fmt.Errorf("event data is empty") - } - - var eventData OutboundEvent - if err := json.Unmarshal(event.EventData, &eventData); err != nil { - return nil, fmt.Errorf("failed to unmarshal event data: %w", err) - } - - if eventData.TxID == "" { - return nil, fmt.Errorf("tx_id not found in event data") - } - - if eventData.UniversalTxID == "" { - return nil, fmt.Errorf("universal_tx_id not found in event data") - } - - return &eventData, nil -} - -// buildOutboundObservation builds an OutboundObservation from event metadata and parsed outbound data -func (ep *EventProcessor) buildOutboundObservation(event *store.Event, outboundData *OutboundEvent) (*uexecutortypes.OutboundObservation, error) { - // Extract txHash from EventID (format: "txHash:logIndex" or "signature:logIndex") - txHash := "" - parts := strings.Split(event.EventID, ":") - if len(parts) > 0 { - txHash = parts[0] - } - - // Convert txHash to hex format if it's in base58 - txHashHex, err := ep.base58ToHex(txHash) - if err != nil { - ep.logger.Warn(). - Str("tx_hash", txHash). - Err(err). - Msg("failed to convert txHash to hex, using original value") - txHashHex = txHash - } - - gasFeeUsed := "0" - if outboundData.GasFeeUsed != "" { - gasFeeUsed = outboundData.GasFeeUsed - } - - observation := &uexecutortypes.OutboundObservation{ - Success: true, - BlockHeight: event.BlockHeight, - TxHash: txHashHex, - ErrorMsg: "", - GasFeeUsed: gasFeeUsed, - Pc20WrapperAddress: outboundData.Pc20WrapperAddress, - } - - return observation, nil -} diff --git a/universalClient/externalchains/common/event_processor_test.go b/universalClient/externalchains/common/event_processor_test.go index 4a08c305..df8a1f12 100644 --- a/universalClient/externalchains/common/event_processor_test.go +++ b/universalClient/externalchains/common/event_processor_test.go @@ -2,7 +2,8 @@ package common import ( "context" - "encoding/json" + "fmt" + "math/big" "testing" "time" @@ -15,1042 +16,256 @@ import ( uexecutortypes "github.com/pushchain/push-chain-node/x/uexecutor/types" ) -func TestNewEventProcessor(t *testing.T) { - t.Run("creates event processor with valid params", func(t *testing.T) { - logger := zerolog.Nop() - chainID := "eip155:1" - - processor := NewEventProcessor(nil, nil, chainID, true, true, logger) - - require.NotNil(t, processor) - assert.Equal(t, chainID, processor.chainID) - assert.False(t, processor.running) - assert.NotNil(t, processor.stopCh) - assert.NotNil(t, processor.chainStore) - }) -} - -func TestEventProcessorIsRunning(t *testing.T) { - t.Run("returns false when not running", func(t *testing.T) { - processor := &EventProcessor{running: false} - assert.False(t, processor.IsRunning()) - }) - - t.Run("returns true when running", func(t *testing.T) { - processor := &EventProcessor{running: true} - assert.True(t, processor.IsRunning()) - }) +type fakeVoteSigner struct { + inboundVotes int + outboundVotes int + txHash string + err error } -func TestEventProcessorStop(t *testing.T) { - t.Run("stop when not running returns nil", func(t *testing.T) { - processor := &EventProcessor{running: false} - err := processor.Stop() - assert.NoError(t, err) - }) +func (f *fakeVoteSigner) VoteInbound(ctx context.Context, inbound *uexecutortypes.Inbound) (string, error) { + if f.err != nil { + return "", f.err + } + f.inboundVotes++ + return f.txHash, nil } -func TestEventProcessorBase58ToHex(t *testing.T) { - logger := zerolog.Nop() - processor := NewEventProcessor(nil, nil, "test-chain", true, true, logger) - - t.Run("empty string returns 0x", func(t *testing.T) { - result, err := processor.base58ToHex("") - require.NoError(t, err) - assert.Equal(t, "0x", result) - }) - - t.Run("already hex returns as is", func(t *testing.T) { - input := "0xabcdef1234567890" - result, err := processor.base58ToHex(input) - require.NoError(t, err) - assert.Equal(t, input, result) - }) - - t.Run("valid base58 converts to hex", func(t *testing.T) { - // "3yZe7d" is base58 for bytes [1, 2, 3, 4] - input := "2VfUX" - result, err := processor.base58ToHex(input) - require.NoError(t, err) - assert.True(t, len(result) > 2) - assert.Equal(t, "0x", result[:2]) - }) - - t.Run("invalid base58 returns error", func(t *testing.T) { - // Base58 doesn't include 0, O, I, l - input := "0OIl" - _, err := processor.base58ToHex(input) - require.Error(t, err) - }) +func (f *fakeVoteSigner) VoteOutbound(ctx context.Context, txID string, utxID string, observation *uexecutortypes.OutboundObservation) (string, error) { + if f.err != nil { + return "", f.err + } + f.outboundVotes++ + return f.txHash, nil } -func TestEventProcessorConstructInbound(t *testing.T) { - logger := zerolog.Nop() - processor := NewEventProcessor(nil, nil, "eip155:1", true, true, logger) - - t.Run("nil event returns error", func(t *testing.T) { - inbound, err := processor.constructInbound(nil) - require.Error(t, err) - assert.Nil(t, inbound) - assert.Contains(t, err.Error(), "event is nil") - }) - - t.Run("nil event data returns error", func(t *testing.T) { - event := &store.Event{ - EventID: "0x123:0", - EventData: nil, - } - inbound, err := processor.constructInbound(event) - require.Error(t, err) - assert.Nil(t, inbound) - assert.Contains(t, err.Error(), "event data is missing") - }) - - t.Run("invalid JSON returns error", func(t *testing.T) { - event := &store.Event{ - EventID: "0x123:0", - EventData: []byte("invalid json"), - } - inbound, err := processor.constructInbound(event) - require.Error(t, err) - assert.Nil(t, inbound) - }) - - t.Run("valid event data constructs inbound", func(t *testing.T) { - eventData := UniversalTx{ - SourceChain: "eip155:1", - LogIndex: 5, - Sender: "0xsender123", - Recipient: "push1recipient", - Token: "0xtoken", - Amount: "1000000", - TxType: 2, // FUNDS - } - eventDataBytes, _ := json.Marshal(eventData) - - event := &store.Event{ - EventID: "0xabc123:5", - EventData: eventDataBytes, - } - - inbound, err := processor.constructInbound(event) - require.NoError(t, err) - require.NotNil(t, inbound) - assert.Equal(t, "eip155:1", inbound.SourceChain) - assert.Equal(t, "0xsender123", inbound.Sender) - assert.Equal(t, "1000000", inbound.Amount) - assert.Equal(t, uexecutortypes.TxType_FUNDS, inbound.TxType) - }) - - t.Run("passes all fields unconditionally to inbound", func(t *testing.T) { - eventData := UniversalTx{ - SourceChain: "eip155:1", - LogIndex: 3, - Sender: "0xsender", - Recipient: "0xrecipient", - Token: "0xtoken", - Amount: "500", - RawPayload: "0xdeadbeef", - VerificationData: "0xsigdata", - RevertFundRecipient: "0xrevert", - TxType: 3, // FUNDS_AND_PAYLOAD - FromCEA: true, - } - eventDataBytes, _ := json.Marshal(eventData) - - event := &store.Event{ - EventID: "0xtxhash:3", - EventData: eventDataBytes, - } - - inbound, err := processor.constructInbound(event) - require.NoError(t, err) - require.NotNil(t, inbound) - assert.Equal(t, "0xrecipient", inbound.Recipient) - assert.Equal(t, "0xdeadbeef", inbound.RawPayload) - assert.Equal(t, "0xsigdata", inbound.VerificationData) - assert.True(t, inbound.IsCEA) - require.NotNil(t, inbound.RevertInstructions) - assert.Equal(t, "0xrevert", inbound.RevertInstructions.FundRecipient) - }) - - t.Run("passes raw payload and verification data for non-payload tx types", func(t *testing.T) { - // Core will strip these — UV just passes everything through - eventData := UniversalTx{ - SourceChain: "eip155:1", - Sender: "0xsender", - Recipient: "0xrecipient", - Amount: "1000", - RawPayload: "0xcafe", - VerificationData: "0xsig", - TxType: 2, // FUNDS (non-payload type) - } - eventDataBytes, _ := json.Marshal(eventData) - - event := &store.Event{ - EventID: "0xhash:0", - EventData: eventDataBytes, - } - - inbound, err := processor.constructInbound(event) - require.NoError(t, err) - assert.Equal(t, "0xrecipient", inbound.Recipient) - assert.Equal(t, "0xcafe", inbound.RawPayload) - assert.Equal(t, "0xsig", inbound.VerificationData) - }) - - t.Run("no revert instructions when revert recipient is empty", func(t *testing.T) { - eventData := UniversalTx{ - SourceChain: "eip155:1", - Sender: "0xsender", - Amount: "100", - TxType: 0, // GAS - RevertFundRecipient: "", - } - eventDataBytes, _ := json.Marshal(eventData) - - event := &store.Event{ - EventID: "0xhash:0", - EventData: eventDataBytes, - } - - inbound, err := processor.constructInbound(event) - require.NoError(t, err) - assert.Nil(t, inbound.RevertInstructions) - }) - - t.Run("tx type mapping", func(t *testing.T) { - testCases := []struct { - txType uint - expected uexecutortypes.TxType - }{ - {0, uexecutortypes.TxType_GAS}, - {1, uexecutortypes.TxType_GAS_AND_PAYLOAD}, - {2, uexecutortypes.TxType_FUNDS}, - {3, uexecutortypes.TxType_FUNDS_AND_PAYLOAD}, - {99, uexecutortypes.TxType_UNSPECIFIED_TX}, // Unknown defaults to unspecified - } - - for _, tc := range testCases { - eventData := UniversalTx{ - SourceChain: "eip155:1", - TxType: tc.txType, - } - eventDataBytes, _ := json.Marshal(eventData) - - event := &store.Event{ - EventID: "0xabc:0", - EventData: eventDataBytes, - } - - inbound, err := processor.constructInbound(event) - require.NoError(t, err) - assert.Equal(t, tc.expected, inbound.TxType, "TxType %d should map to %v", tc.txType, tc.expected) - } - }) +type fakeEventHandler struct { + handled []string + err error } -func TestEventProcessorParseOutboundEventData(t *testing.T) { - logger := zerolog.Nop() - processor := NewEventProcessor(nil, nil, "eip155:1", true, true, logger) - - t.Run("nil event returns error", func(t *testing.T) { - data, err := processor.parseOutboundEventData(nil) - require.Error(t, err) - assert.Nil(t, data) - assert.Contains(t, err.Error(), "event is nil") - }) - - t.Run("empty event data returns error", func(t *testing.T) { - event := &store.Event{ - EventID: "test", - EventData: []byte{}, - } - data, err := processor.parseOutboundEventData(event) - require.Error(t, err) - assert.Nil(t, data) - assert.Contains(t, err.Error(), "event data is empty") - }) - - t.Run("valid outbound event extracts IDs and gas fee", func(t *testing.T) { - eventData := OutboundEvent{ - TxID: "0x1234", - UniversalTxID: "0xabcd", - GasFeeUsed: "42000000000000", - } - eventDataBytes, _ := json.Marshal(eventData) - - event := &store.Event{ - EventID: "test", - EventData: eventDataBytes, - } - - data, err := processor.parseOutboundEventData(event) - require.NoError(t, err) - assert.Equal(t, "0x1234", data.TxID) - assert.Equal(t, "0xabcd", data.UniversalTxID) - assert.Equal(t, "42000000000000", data.GasFeeUsed) - }) - - t.Run("missing tx_id returns error", func(t *testing.T) { - eventData := OutboundEvent{ - TxID: "", - UniversalTxID: "0xabcd", - } - eventDataBytes, _ := json.Marshal(eventData) - - event := &store.Event{ - EventID: "test", - EventData: eventDataBytes, - } - - data, err := processor.parseOutboundEventData(event) - require.Error(t, err) - assert.Nil(t, data) - assert.Contains(t, err.Error(), "tx_id not found") - }) - - t.Run("missing universal_tx_id returns error", func(t *testing.T) { - eventData := OutboundEvent{ - TxID: "0x1234", - UniversalTxID: "", - } - eventDataBytes, _ := json.Marshal(eventData) - - event := &store.Event{ - EventID: "test", - EventData: eventDataBytes, - } - - data, err := processor.parseOutboundEventData(event) - require.Error(t, err) - assert.Nil(t, data) - assert.Contains(t, err.Error(), "universal_tx_id not found") - }) +func (f *fakeEventHandler) HandleEvent(ctx context.Context, event *store.Event) error { + f.handled = append(f.handled, event.EventID) + return f.err } -func TestEventProcessorBuildOutboundObservation(t *testing.T) { - logger := zerolog.Nop() - processor := NewEventProcessor(nil, nil, "eip155:1", true, true, logger) - - t.Run("builds observation with gas fee from parsed data", func(t *testing.T) { - outboundData := &OutboundEvent{ - TxID: "0x1234", - UniversalTxID: "0xabcd", - GasFeeUsed: "42000000000000", - } - - event := &store.Event{ - EventID: "0xabc123:5", - BlockHeight: 12345, - } - - obs, err := processor.buildOutboundObservation(event, outboundData) - require.NoError(t, err) - require.NotNil(t, obs) - assert.True(t, obs.Success) - assert.Equal(t, uint64(12345), obs.BlockHeight) - assert.Equal(t, "0xabc123", obs.TxHash) - assert.Equal(t, "42000000000000", obs.GasFeeUsed) - }) - - t.Run("missing gas fee defaults to 0", func(t *testing.T) { - outboundData := &OutboundEvent{ - TxID: "0x1234", - UniversalTxID: "0xabcd", - } - - event := &store.Event{ - EventID: "0xabc123:5", - BlockHeight: 12345, - } - - obs, err := processor.buildOutboundObservation(event, outboundData) - require.NoError(t, err) - require.NotNil(t, obs) - assert.Equal(t, "0", obs.GasFeeUsed) - }) - - t.Run("handles base58 tx hash", func(t *testing.T) { - outboundData := &OutboundEvent{ - TxID: "0x1234", - UniversalTxID: "0xabcd", - } - - event := &store.Event{ - EventID: "2VfUX:0", // Base58 encoded - BlockHeight: 100, - } - - obs, err := processor.buildOutboundObservation(event, outboundData) - require.NoError(t, err) - require.NotNil(t, obs) - assert.True(t, len(obs.TxHash) >= 2) - }) +func newTestDB(t *testing.T) *ucdb.DB { + t.Helper() + database, err := ucdb.OpenInMemoryDB(true) + require.NoError(t, err) + t.Cleanup(func() { _ = database.Close() }) + return database } -func TestProcessOutboundEvent(t *testing.T) { - logger := zerolog.Nop() - ctx := context.Background() - - setupDB := func(t *testing.T) *ucdb.DB { - t.Helper() - database, err := ucdb.OpenInMemoryDB(true) - require.NoError(t, err) - return database - } - - t.Run("nil event data returns parse error", func(t *testing.T) { - database := setupDB(t) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - event := &store.Event{ - EventID: "0xabc:0", - EventData: nil, - } - err := ep.processOutboundEvent(ctx, event) - require.Error(t, err) - assert.Contains(t, err.Error(), "failed to parse outbound event data") - }) - - t.Run("empty event data returns parse error", func(t *testing.T) { - database := setupDB(t) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - event := &store.Event{ - EventID: "0xabc:0", - EventData: []byte{}, - } - err := ep.processOutboundEvent(ctx, event) - require.Error(t, err) - assert.Contains(t, err.Error(), "failed to parse outbound event data") - }) - - t.Run("invalid JSON event data returns parse error", func(t *testing.T) { - database := setupDB(t) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - event := &store.Event{ - EventID: "0xabc:0", - EventData: []byte("not json"), - } - err := ep.processOutboundEvent(ctx, event) - require.Error(t, err) - assert.Contains(t, err.Error(), "failed to parse outbound event data") - }) - - t.Run("missing tx_id returns parse error", func(t *testing.T) { - database := setupDB(t) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - eventData, _ := json.Marshal(OutboundEvent{ - TxID: "", - UniversalTxID: "0xutxid", - }) - event := &store.Event{ - EventID: "0xabc:0", - EventData: eventData, - } - err := ep.processOutboundEvent(ctx, event) - require.Error(t, err) - assert.Contains(t, err.Error(), "failed to parse outbound event data") - }) - - t.Run("missing universal_tx_id returns parse error", func(t *testing.T) { - database := setupDB(t) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - eventData, _ := json.Marshal(OutboundEvent{ - TxID: "0xtxid", - UniversalTxID: "", - }) - event := &store.Event{ - EventID: "0xabc:0", - EventData: eventData, - } - err := ep.processOutboundEvent(ctx, event) - require.Error(t, err) - assert.Contains(t, err.Error(), "failed to parse outbound event data") +func seedConfirmedEvent(t *testing.T, database *ucdb.DB, eventID, eventType string, eventData []byte) { + t.Helper() + result := database.Client().Create(&store.Event{ + EventID: eventID, + Type: eventType, + ConfirmationType: store.ConfirmationInstant, + Status: store.StatusConfirmed, + EventData: eventData, }) + require.NoError(t, result.Error) } -func TestProcessInboundEvent(t *testing.T) { - logger := zerolog.Nop() - ctx := context.Background() - - setupDB := func(t *testing.T) *ucdb.DB { - t.Helper() - database, err := ucdb.OpenInMemoryDB(true) - require.NoError(t, err) - return database - } - - t.Run("nil event data returns construct error", func(t *testing.T) { - database := setupDB(t) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - event := &store.Event{ - EventID: "0xabc:0", - EventData: nil, - } - err := ep.processInboundEvent(ctx, event) - require.Error(t, err) - assert.Contains(t, err.Error(), "failed to construct inbound") - }) - - t.Run("invalid JSON event data returns construct error", func(t *testing.T) { - database := setupDB(t) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - event := &store.Event{ - EventID: "0xabc:0", - EventData: []byte("{not valid json}"), - } - err := ep.processInboundEvent(ctx, event) - require.Error(t, err) - assert.Contains(t, err.Error(), "failed to construct inbound") - }) +func TestNewEventProcessor(t *testing.T) { + processor := NewEventProcessor(nil, "eip155:1", zerolog.Nop()) + + require.NotNil(t, processor) + assert.Equal(t, "eip155:1", processor.chainID) + assert.False(t, processor.running) + assert.NotNil(t, processor.stopCh) + assert.NotNil(t, processor.chainStore) + assert.Empty(t, processor.handlers) } -func TestProcessConfirmedEventsRouting(t *testing.T) { - logger := zerolog.Nop() - ctx := context.Background() - - setupDB := func(t *testing.T, events []store.Event) *ucdb.DB { - t.Helper() - database, err := ucdb.OpenInMemoryDB(true) - require.NoError(t, err) - for _, e := range events { - result := database.Client().Create(&e) - require.NoError(t, result.Error) - } - return database - } - - t.Run("no confirmed events returns nil", func(t *testing.T) { - database := setupDB(t, nil) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) +func TestEventProcessor_DispatchesByType(t *testing.T) { + database := newTestDB(t) + ep := NewEventProcessor(database, "eip155:1", zerolog.Nop()) - err := ep.processConfirmedEvents(ctx) - require.NoError(t, err) - }) - - t.Run("only pending events are ignored", func(t *testing.T) { - database := setupDB(t, []store.Event{ - { - EventID: "0xpending:0", - Status: store.StatusPending, - Type: store.EventTypeInbound, - EventData: []byte("{}"), - }, - }) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - err := ep.processConfirmedEvents(ctx) - require.NoError(t, err) - - // Event should remain PENDING (not picked up) - var evt store.Event - database.Client().Where("event_id = ?", "0xpending:0").First(&evt) - assert.Equal(t, store.StatusPending, evt.Status) - }) - - t.Run("inbound with bad data fails gracefully and continues to next event", func(t *testing.T) { - database := setupDB(t, []store.Event{ - { - EventID: "0xbad_inbound:0", - Status: store.StatusConfirmed, - Type: store.EventTypeInbound, - EventData: []byte("not json"), - }, - { - EventID: "0xbad_inbound2:0", - Status: store.StatusConfirmed, - Type: store.EventTypeInbound, - EventData: nil, - }, - }) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - // Should not return error - errors on individual events are logged and skipped - err := ep.processConfirmedEvents(ctx) - require.NoError(t, err) - - // Both events should remain CONFIRMED (failed to process, not updated) - var evt1, evt2 store.Event - database.Client().Where("event_id = ?", "0xbad_inbound:0").First(&evt1) - assert.Equal(t, store.StatusConfirmed, evt1.Status) - database.Client().Where("event_id = ?", "0xbad_inbound2:0").First(&evt2) - assert.Equal(t, store.StatusConfirmed, evt2.Status) - }) - - t.Run("outbound with bad data fails gracefully and continues to next event", func(t *testing.T) { - database := setupDB(t, []store.Event{ - { - EventID: "0xbad_outbound:0", - Status: store.StatusConfirmed, - Type: store.EventTypeOutbound, - EventData: []byte("not json"), - }, - { - EventID: "0xbad_outbound2:0", - Status: store.StatusConfirmed, - Type: store.EventTypeOutbound, - EventData: []byte{}, - }, - }) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - err := ep.processConfirmedEvents(ctx) - require.NoError(t, err) - - // Both events should remain CONFIRMED - var evt1, evt2 store.Event - database.Client().Where("event_id = ?", "0xbad_outbound:0").First(&evt1) - assert.Equal(t, store.StatusConfirmed, evt1.Status) - database.Client().Where("event_id = ?", "0xbad_outbound2:0").First(&evt2) - assert.Equal(t, store.StatusConfirmed, evt2.Status) - }) - - t.Run("mixed inbound and outbound with bad data both fail gracefully", func(t *testing.T) { - database := setupDB(t, []store.Event{ - { - EventID: "0xin:0", - Status: store.StatusConfirmed, - Type: store.EventTypeInbound, - EventData: []byte("bad"), - }, - { - EventID: "0xout:0", - Status: store.StatusConfirmed, - Type: store.EventTypeOutbound, - EventData: []byte("bad"), - }, - }) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) + inboundHandler := &fakeEventHandler{} + ep.RegisterHandler(store.EventTypeInbound, inboundHandler) - err := ep.processConfirmedEvents(ctx) - require.NoError(t, err) - - var inEvt, outEvt store.Event - database.Client().Where("event_id = ?", "0xin:0").First(&inEvt) - assert.Equal(t, store.StatusConfirmed, inEvt.Status) - database.Client().Where("event_id = ?", "0xout:0").First(&outEvt) - assert.Equal(t, store.StatusConfirmed, outEvt.Status) - }) - - t.Run("outbound missing tx_id in valid JSON stays CONFIRMED", func(t *testing.T) { - eventData, _ := json.Marshal(OutboundEvent{ - TxID: "", - UniversalTxID: "0xutxid", - }) - database := setupDB(t, []store.Event{ - { - EventID: "0xno_txid:0", - Status: store.StatusConfirmed, - Type: store.EventTypeOutbound, - EventData: eventData, - }, - }) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - err := ep.processConfirmedEvents(ctx) - require.NoError(t, err) - - var evt store.Event - database.Client().Where("event_id = ?", "0xno_txid:0").First(&evt) - assert.Equal(t, store.StatusConfirmed, evt.Status) - }) - - t.Run("unknown event type is silently skipped", func(t *testing.T) { - database := setupDB(t, []store.Event{ - { - EventID: "0xunknown:0", - Status: store.StatusConfirmed, - Type: "UNKNOWN_TYPE", - EventData: []byte("{}"), - }, - }) - defer database.Close() - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) + seedConfirmedEvent(t, database, "0xin:0", store.EventTypeInbound, []byte("{}")) + seedConfirmedEvent(t, database, "0xout:0", store.EventTypeOutbound, []byte("{}")) // no handler registered - err := ep.processConfirmedEvents(ctx) - require.NoError(t, err) + require.NoError(t, ep.processConfirmedEvents(context.Background())) - // Event should remain CONFIRMED (no handler for this type) - var evt store.Event - database.Client().Where("event_id = ?", "0xunknown:0").First(&evt) - assert.Equal(t, store.StatusConfirmed, evt.Status) - }) + assert.Equal(t, []string{"0xin:0"}, inboundHandler.handled) } -func TestProcessLoopContextCancellation(t *testing.T) { - logger := zerolog.Nop() - database, err := ucdb.OpenInMemoryDB(true) - require.NoError(t, err) - defer database.Close() - - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - t.Run("processLoop exits promptly on context cancel", func(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - - err := ep.Start(ctx) - require.NoError(t, err) - assert.True(t, ep.IsRunning()) - - // Cancel context and wait for stop - cancel() +func TestEventProcessor_HandlerErrorKeepsProcessing(t *testing.T) { + database := newTestDB(t) + ep := NewEventProcessor(database, "eip155:1", zerolog.Nop()) - // The wg.Wait inside Stop() will block until processLoop exits - done := make(chan struct{}) - go func() { - ep.Stop() - close(done) - }() + failing := &fakeEventHandler{err: fmt.Errorf("boom")} + ep.RegisterHandler(store.EventTypeInbound, failing) - select { - case <-done: - // processLoop exited within reasonable time - case <-time.After(10 * time.Second): - t.Fatal("processLoop did not exit within 10 seconds after context cancellation") - } + seedConfirmedEvent(t, database, "0xin:0", store.EventTypeInbound, []byte("{}")) + seedConfirmedEvent(t, database, "0xin:1", store.EventTypeInbound, []byte("{}")) - assert.False(t, ep.IsRunning()) - }) -} + require.NoError(t, ep.processConfirmedEvents(context.Background())) -func TestProcessLoopStopChannel(t *testing.T) { - logger := zerolog.Nop() - database, err := ucdb.OpenInMemoryDB(true) + // both attempted despite errors, both still CONFIRMED for retry + assert.Len(t, failing.handled, 2) + events, err := NewChainStore(database).GetConfirmedEvents(10) require.NoError(t, err) - defer database.Close() - - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - t.Run("processLoop exits promptly on stop signal", func(t *testing.T) { - ctx := context.Background() - - err := ep.Start(ctx) - require.NoError(t, err) - assert.True(t, ep.IsRunning()) - - done := make(chan struct{}) - go func() { - ep.Stop() - close(done) - }() - - select { - case <-done: - // processLoop exited promptly - case <-time.After(10 * time.Second): - t.Fatal("processLoop did not exit within 10 seconds after stop signal") - } - - assert.False(t, ep.IsRunning()) - }) -} - -func TestProcessConfirmedEventsDBError(t *testing.T) { - logger := zerolog.Nop() - ctx := context.Background() - - t.Run("nil database returns error", func(t *testing.T) { - ep := &EventProcessor{ - chainStore: NewChainStore(nil), - logger: logger, - chainID: "eip155:1", - inboundEnabled: true, - outboundEnabled: true, - } - - err := ep.processConfirmedEvents(ctx) - require.Error(t, err) - assert.Contains(t, err.Error(), "failed to get confirmed events") - }) -} - -func TestEventProcessorStruct(t *testing.T) { - t.Run("struct has expected fields", func(t *testing.T) { - ep := &EventProcessor{} - assert.Nil(t, ep.signer) - assert.Nil(t, ep.chainStore) - assert.Empty(t, ep.chainID) - assert.False(t, ep.running) - assert.Nil(t, ep.stopCh) - assert.False(t, ep.inboundEnabled) - assert.False(t, ep.outboundEnabled) - }) + assert.Len(t, events, 2) } -func TestNewEventProcessorEnabledFlags(t *testing.T) { - logger := zerolog.Nop() +func TestEventProcessor_PendingEventsIgnored(t *testing.T) { + database := newTestDB(t) + ep := NewEventProcessor(database, "eip155:1", zerolog.Nop()) - t.Run("both enabled", func(t *testing.T) { - ep := NewEventProcessor(nil, nil, "eip155:1", true, true, logger) - assert.True(t, ep.inboundEnabled) - assert.True(t, ep.outboundEnabled) - }) + handler := &fakeEventHandler{} + ep.RegisterHandler(store.EventTypeInbound, handler) - t.Run("inbound only", func(t *testing.T) { - ep := NewEventProcessor(nil, nil, "eip155:1", true, false, logger) - assert.True(t, ep.inboundEnabled) - assert.False(t, ep.outboundEnabled) + result := database.Client().Create(&store.Event{ + EventID: "0xpending:0", + Type: store.EventTypeInbound, + ConfirmationType: store.ConfirmationInstant, + Status: store.StatusPending, + EventData: []byte("{}"), }) + require.NoError(t, result.Error) - t.Run("outbound only", func(t *testing.T) { - ep := NewEventProcessor(nil, nil, "eip155:1", false, true, logger) - assert.False(t, ep.inboundEnabled) - assert.True(t, ep.outboundEnabled) - }) + require.NoError(t, ep.processConfirmedEvents(context.Background())) - t.Run("both disabled", func(t *testing.T) { - ep := NewEventProcessor(nil, nil, "eip155:1", false, false, logger) - assert.False(t, ep.inboundEnabled) - assert.False(t, ep.outboundEnabled) - }) + assert.Empty(t, handler.handled) } -func TestEventProcessorStartDoubleStart(t *testing.T) { - logger := zerolog.Nop() - database, err := ucdb.OpenInMemoryDB(true) - require.NoError(t, err) - defer database.Close() - - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - // First start should succeed - err = ep.Start(ctx) - require.NoError(t, err) - assert.True(t, ep.IsRunning()) +func TestEventProcessor_NilDatabaseErrors(t *testing.T) { + ep := NewEventProcessor(nil, "eip155:1", zerolog.Nop()) + ep.RegisterHandler(store.EventTypeInbound, &fakeEventHandler{}) - // Second start should be rejected - err = ep.Start(ctx) + err := ep.processConfirmedEvents(context.Background()) require.Error(t, err) - assert.Contains(t, err.Error(), "already running") - assert.True(t, ep.IsRunning()) - - // Clean up - err = ep.Stop() - require.NoError(t, err) - assert.False(t, ep.IsRunning()) + assert.Contains(t, err.Error(), "failed to get confirmed events") } -func TestEventProcessorStopIdempotent(t *testing.T) { - logger := zerolog.Nop() - database, err := ucdb.OpenInMemoryDB(true) - require.NoError(t, err) - defer database.Close() - - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) +func TestEventProcessor_Lifecycle(t *testing.T) { + database := newTestDB(t) + ep := NewEventProcessor(database, "eip155:1", zerolog.Nop()) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - // Start the processor - err = ep.Start(ctx) - require.NoError(t, err) - assert.True(t, ep.IsRunning()) - - // First stop - err = ep.Stop() - require.NoError(t, err) - assert.False(t, ep.IsRunning()) - - // Second stop should be idempotent (no error, no panic) - err = ep.Stop() - require.NoError(t, err) - assert.False(t, ep.IsRunning()) - - // Third stop also fine - err = ep.Stop() - require.NoError(t, err) -} - -func TestEventProcessorIsRunningStateTransitions(t *testing.T) { - logger := zerolog.Nop() - database, err := ucdb.OpenInMemoryDB(true) - require.NoError(t, err) - defer database.Close() - - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) - - // Initial state: not running + // initial state assert.False(t, ep.IsRunning()) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - // After start: running - err = ep.Start(ctx) - require.NoError(t, err) + // start + require.NoError(t, ep.Start(ctx)) assert.True(t, ep.IsRunning()) - // After stop: not running - err = ep.Stop() - require.NoError(t, err) + // double start rejected + err := ep.Start(ctx) + require.Error(t, err) + assert.Contains(t, err.Error(), "already running") + + // stop, idempotent + require.NoError(t, ep.Stop()) assert.False(t, ep.IsRunning()) + require.NoError(t, ep.Stop()) - // Can restart after stop - err = ep.Start(ctx) - require.NoError(t, err) + // restart works + require.NoError(t, ep.Start(ctx)) assert.True(t, ep.IsRunning()) - - // Clean up - err = ep.Stop() - require.NoError(t, err) - assert.False(t, ep.IsRunning()) + require.NoError(t, ep.Stop()) } -func TestEventProcessorStopViaContextCancel(t *testing.T) { - logger := zerolog.Nop() - database, err := ucdb.OpenInMemoryDB(true) - require.NoError(t, err) - defer database.Close() - - ep := NewEventProcessor(nil, database, "eip155:1", true, true, logger) +func TestEventProcessor_StopViaContextCancel(t *testing.T) { + database := newTestDB(t) + ep := NewEventProcessor(database, "eip155:1", zerolog.Nop()) ctx, cancel := context.WithCancel(context.Background()) - - err = ep.Start(ctx) - require.NoError(t, err) + require.NoError(t, ep.Start(ctx)) assert.True(t, ep.IsRunning()) - // Cancel context - the processLoop should exit cancel() - // Stop should still work cleanly after context cancellation - err = ep.Stop() - require.NoError(t, err) + done := make(chan struct{}) + go func() { + _ = ep.Stop() + close(done) + }() + + select { + case <-done: + case <-time.After(10 * time.Second): + t.Fatal("processLoop did not exit after context cancellation") + } assert.False(t, ep.IsRunning()) } -func TestProcessConfirmedEventsEnabledFlags(t *testing.T) { - logger := zerolog.Nop() - ctx := context.Background() - - // Helper to create an in-memory DB and seed confirmed events - setupDB := func(t *testing.T, events []store.Event) *ucdb.DB { - t.Helper() - database, err := ucdb.OpenInMemoryDB(true) +func TestBase58ToHex(t *testing.T) { + t.Run("empty string returns 0x", func(t *testing.T) { + result, err := base58ToHex("") require.NoError(t, err) - for _, e := range events { - result := database.Client().Create(&e) - require.NoError(t, result.Error) - } - return database - } - - inboundEventData, _ := json.Marshal(UniversalTx{ - SourceChain: "eip155:1", - Sender: "0xsender", - Amount: "1000", - TxType: 2, + assert.Equal(t, "0x", result) }) - outboundEventData, _ := json.Marshal(OutboundEvent{ - TxID: "0xtxid", - UniversalTxID: "0xutxid", + t.Run("already hex returns as is", func(t *testing.T) { + input := "0xabcdef1234567890" + result, err := base58ToHex(input) + require.NoError(t, err) + assert.Equal(t, input, result) }) - makeEvents := func() []store.Event { - return []store.Event{ - { - EventID: "0xaaa:0", - Status: store.StatusConfirmed, - Type: store.EventTypeInbound, - EventData: inboundEventData, - }, - { - EventID: "0xbbb:0", - Status: store.StatusConfirmed, - Type: store.EventTypeOutbound, - EventData: outboundEventData, - }, - } - } - - t.Run("inbound disabled skips inbound events, leaves them CONFIRMED", func(t *testing.T) { - database := setupDB(t, makeEvents()) - // inbound=false, outbound=false (no signer so outbound will also fail to vote, but that's ok) - ep := NewEventProcessor(nil, database, "eip155:1", false, false, logger) - - err := ep.processConfirmedEvents(ctx) + t.Run("valid base58 converts to hex", func(t *testing.T) { + result, err := base58ToHex("2VfUX") require.NoError(t, err) + assert.True(t, len(result) > 2) + assert.Equal(t, "0x", result[:2]) + }) - // Inbound event should still be CONFIRMED (skipped, not processed) - var inboundEvt store.Event - database.Client().Where("event_id = ?", "0xaaa:0").First(&inboundEvt) - assert.Equal(t, store.StatusConfirmed, inboundEvt.Status) + t.Run("invalid base58 returns error", func(t *testing.T) { + // Base58 doesn't include 0, O, I, l + _, err := base58ToHex("0OIl") + require.Error(t, err) }) +} - t.Run("outbound disabled skips outbound events, leaves them CONFIRMED", func(t *testing.T) { - database := setupDB(t, makeEvents()) - ep := NewEventProcessor(nil, database, "eip155:1", false, false, logger) +func TestEventTxHash(t *testing.T) { + t.Run("hex event id", func(t *testing.T) { + assert.Equal(t, "0xabc123", eventTxHash("0xabc123:5")) + }) - err := ep.processConfirmedEvents(ctx) - require.NoError(t, err) + t.Run("base58 event id converts", func(t *testing.T) { + got := eventTxHash("2VfUX:0") + assert.Equal(t, "0x", got[:2]) + }) - // Outbound event should still be CONFIRMED (skipped, not processed) - var outboundEvt store.Event - database.Client().Where("event_id = ?", "0xbbb:0").First(&outboundEvt) - assert.Equal(t, store.StatusConfirmed, outboundEvt.Status) + t.Run("invalid base58 falls back to raw value", func(t *testing.T) { + assert.Equal(t, "0OIl", eventTxHash("0OIl:0")) }) +} - t.Run("inbound enabled but outbound disabled skips only outbound", func(t *testing.T) { - // Seed only outbound events so we don't hit nil signer panic on inbound - database := setupDB(t, []store.Event{ - { - EventID: "0xbbb:0", - Status: store.StatusConfirmed, - Type: store.EventTypeOutbound, - EventData: outboundEventData, - }, - }) - ep := NewEventProcessor(nil, database, "eip155:1", true, false, logger) +func TestMarkEventCompleted(t *testing.T) { + database := newTestDB(t) + cs := NewChainStore(database) + seedConfirmedEvent(t, database, "0xdone:0", store.EventTypeInbound, []byte("{}")) - err := ep.processConfirmedEvents(ctx) - require.NoError(t, err) + event := &store.Event{EventID: "0xdone:0", Type: store.EventTypeInbound} + require.NoError(t, markEventCompleted(cs, zerolog.Nop(), event, "0xvote")) - // Outbound event should still be CONFIRMED (skipped due to outbound disabled) - var outboundEvt store.Event - database.Client().Where("event_id = ?", "0xbbb:0").First(&outboundEvt) - assert.Equal(t, store.StatusConfirmed, outboundEvt.Status) - }) + rows, err := cs.UpdateEventStatus("0xdone:0", store.StatusCompleted, store.StatusCompleted) + require.NoError(t, err) + assert.Equal(t, int64(1), rows) - t.Run("outbound enabled but inbound disabled skips only inbound", func(t *testing.T) { - // Seed only inbound events so we don't hit nil signer panic on outbound - database := setupDB(t, []store.Event{ - { - EventID: "0xaaa:0", - Status: store.StatusConfirmed, - Type: store.EventTypeInbound, - EventData: inboundEventData, - }, - }) - ep := NewEventProcessor(nil, database, "eip155:1", false, true, logger) + // already completed: no-op, no error + require.NoError(t, markEventCompleted(cs, zerolog.Nop(), event, "0xvote2")) +} - err := ep.processConfirmedEvents(ctx) - require.NoError(t, err) +func TestEncodeUint256Result(t *testing.T) { + out, err := EncodeUint256Result(big.NewInt(1_000_000)) + require.NoError(t, err) + require.Len(t, out, 32) + assert.Equal(t, big.NewInt(1_000_000), new(big.Int).SetBytes(out)) - // Inbound event should still be CONFIRMED (skipped due to inbound disabled) - var inboundEvt store.Event - database.Client().Where("event_id = ?", "0xaaa:0").First(&inboundEvt) - assert.Equal(t, store.StatusConfirmed, inboundEvt.Status) - }) + out, err = EncodeUint256Result(nil) + require.NoError(t, err) + assert.Equal(t, make([]byte, 32), out) + + _, err = EncodeUint256Result(big.NewInt(-1)) + assert.Error(t, err) } diff --git a/universalClient/externalchains/common/inbound_observation_event_processor.go b/universalClient/externalchains/common/inbound_observation_event_processor.go new file mode 100644 index 00000000..c72f8842 --- /dev/null +++ b/universalClient/externalchains/common/inbound_observation_event_processor.go @@ -0,0 +1,133 @@ +package common + +import ( + "context" + "encoding/json" + "fmt" + "strconv" + + "github.com/pushchain/push-chain-node/universalClient/db" + "github.com/pushchain/push-chain-node/universalClient/store" + uexecutortypes "github.com/pushchain/push-chain-node/x/uexecutor/types" + "github.com/rs/zerolog" +) + +// InboundObservation is the inbound observation payload stored for INBOUND events +type InboundObservation struct { + SourceChain string `json:"sourceChain"` + LogIndex uint `json:"logIndex"` + Sender string `json:"sender"` + Recipient string `json:"recipient"` + Token string `json:"bridgeToken"` + Amount string `json:"bridgeAmount"` // uint256 as decimal string + RawPayload string `json:"rawPayload,omitempty"` // hex-encoded raw payload bytes from source chain + VerificationData string `json:"verificationData"` + RevertFundRecipient string `json:"revertFundRecipient,omitempty"` + TxType uint `json:"txType"` // enum backing uint as decimal string + FromCEA bool `json:"fromCEA"` // true if inbound is initiated by a CEA +} + +// InboundObservationEventProcessor handles INBOUND events: it builds the +// inbound observation from the stored event and votes it on Push chain. +type InboundObservationEventProcessor struct { + signer VoteSigner + chainStore *ChainStore + logger zerolog.Logger +} + +// NewInboundObservationEventProcessor creates the handler for INBOUND events. +func NewInboundObservationEventProcessor( + signer VoteSigner, + database *db.DB, + logger zerolog.Logger, +) *InboundObservationEventProcessor { + return &InboundObservationEventProcessor{ + signer: signer, + chainStore: NewChainStore(database), + logger: logger.With().Str("component", "inbound_observation_event_processor").Logger(), + } +} + +// HandleEvent implements EventHandler for INBOUND events. +func (p *InboundObservationEventProcessor) HandleEvent(ctx context.Context, event *store.Event) error { + p.logger.Debug(). + Str("event_id", event.EventID). + Msg("processing inbound event") + + // Extract inbound data from event + inbound, err := p.buildInboundObservation(event) + if err != nil { + return fmt.Errorf("failed to build inbound observation: %w", err) + } + + // Execute vote on blockchain + voteTxHash, err := p.signer.VoteInbound(ctx, inbound) + if err != nil { + return fmt.Errorf("failed to vote on inbound - keeping status for retry: %w", err) + } + + return markEventCompleted(p.chainStore, p.logger, event, voteTxHash) +} + +// buildInboundObservation builds an Inbound observation from event data +func (p *InboundObservationEventProcessor) buildInboundObservation(event *store.Event) (*uexecutortypes.Inbound, error) { + var eventData InboundObservation + + if event == nil { + return nil, fmt.Errorf("event is nil") + } + + if event.EventData == nil { + return nil, fmt.Errorf("event data is missing for event_id: %s", event.EventID) + } + + if err := json.Unmarshal(event.EventData, &eventData); err != nil { + return nil, fmt.Errorf("failed to unmarshal event data: %w", err) + } + + // Map txType from eventData to proper enum value + txType := uexecutortypes.TxType_UNSPECIFIED_TX + switch eventData.TxType { + case 0: + txType = uexecutortypes.TxType_GAS + case 1: + txType = uexecutortypes.TxType_GAS_AND_PAYLOAD + case 2: + txType = uexecutortypes.TxType_FUNDS + case 3: + txType = uexecutortypes.TxType_FUNDS_AND_PAYLOAD + default: + txType = uexecutortypes.TxType_UNSPECIFIED_TX + } + + txHashHex := eventTxHash(event.EventID) + + inboundMsg := &uexecutortypes.Inbound{ + SourceChain: eventData.SourceChain, + TxHash: txHashHex, + Sender: eventData.Sender, + Recipient: eventData.Recipient, + Amount: eventData.Amount, + AssetAddr: eventData.Token, + LogIndex: strconv.FormatUint(uint64(eventData.LogIndex), 10), + TxType: txType, + IsCEA: eventData.FromCEA, + RawPayload: eventData.RawPayload, + } + + // Set revert instructions if revert fund recipient is present + if eventData.RevertFundRecipient != "" { + inboundMsg.RevertInstructions = &uexecutortypes.RevertInstructions{ + FundRecipient: eventData.RevertFundRecipient, + } + } + + // Use event's VerificationData if present, otherwise fall back to txHash + if eventData.VerificationData == "" || eventData.VerificationData == "0x" { + inboundMsg.VerificationData = txHashHex + } else { + inboundMsg.VerificationData = eventData.VerificationData + } + + return inboundMsg, nil +} diff --git a/universalClient/externalchains/common/inbound_observation_event_processor_test.go b/universalClient/externalchains/common/inbound_observation_event_processor_test.go new file mode 100644 index 00000000..4abfe0ab --- /dev/null +++ b/universalClient/externalchains/common/inbound_observation_event_processor_test.go @@ -0,0 +1,214 @@ +package common + +import ( + "context" + "encoding/json" + "fmt" + "testing" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/pushchain/push-chain-node/universalClient/store" + uexecutortypes "github.com/pushchain/push-chain-node/x/uexecutor/types" +) + +func TestInboundBuildInboundObservation(t *testing.T) { + processor := NewInboundObservationEventProcessor(nil, nil, zerolog.Nop()) + + t.Run("nil event returns error", func(t *testing.T) { + inbound, err := processor.buildInboundObservation(nil) + require.Error(t, err) + assert.Nil(t, inbound) + assert.Contains(t, err.Error(), "event is nil") + }) + + t.Run("nil event data returns error", func(t *testing.T) { + event := &store.Event{ + EventID: "0x123:0", + EventData: nil, + } + inbound, err := processor.buildInboundObservation(event) + require.Error(t, err) + assert.Nil(t, inbound) + assert.Contains(t, err.Error(), "event data is missing") + }) + + t.Run("invalid JSON returns error", func(t *testing.T) { + event := &store.Event{ + EventID: "0x123:0", + EventData: []byte("invalid json"), + } + inbound, err := processor.buildInboundObservation(event) + require.Error(t, err) + assert.Nil(t, inbound) + }) + + t.Run("valid event data constructs inbound", func(t *testing.T) { + eventData := InboundObservation{ + SourceChain: "eip155:1", + LogIndex: 5, + Sender: "0xsender123", + Recipient: "push1recipient", + Token: "0xtoken", + Amount: "1000000", + TxType: 2, // FUNDS + } + eventDataBytes, _ := json.Marshal(eventData) + + event := &store.Event{ + EventID: "0xabc123:5", + EventData: eventDataBytes, + } + + inbound, err := processor.buildInboundObservation(event) + require.NoError(t, err) + require.NotNil(t, inbound) + assert.Equal(t, "eip155:1", inbound.SourceChain) + assert.Equal(t, "0xsender123", inbound.Sender) + assert.Equal(t, "1000000", inbound.Amount) + assert.Equal(t, "0xabc123", inbound.TxHash) + assert.Equal(t, uexecutortypes.TxType_FUNDS, inbound.TxType) + }) + + t.Run("passes all fields unconditionally to inbound", func(t *testing.T) { + eventData := InboundObservation{ + SourceChain: "eip155:1", + LogIndex: 3, + Sender: "0xsender", + Recipient: "0xrecipient", + Token: "0xtoken", + Amount: "500", + RawPayload: "0xdeadbeef", + VerificationData: "0xsigdata", + RevertFundRecipient: "0xrevert", + TxType: 3, // FUNDS_AND_PAYLOAD + FromCEA: true, + } + eventDataBytes, _ := json.Marshal(eventData) + + event := &store.Event{ + EventID: "0xtxhash:3", + EventData: eventDataBytes, + } + + inbound, err := processor.buildInboundObservation(event) + require.NoError(t, err) + require.NotNil(t, inbound) + assert.Equal(t, "0xrecipient", inbound.Recipient) + assert.Equal(t, "0xdeadbeef", inbound.RawPayload) + assert.Equal(t, "0xsigdata", inbound.VerificationData) + assert.True(t, inbound.IsCEA) + require.NotNil(t, inbound.RevertInstructions) + assert.Equal(t, "0xrevert", inbound.RevertInstructions.FundRecipient) + }) + + t.Run("no revert instructions when revert recipient is empty", func(t *testing.T) { + eventData := InboundObservation{ + SourceChain: "eip155:1", + Sender: "0xsender", + Amount: "100", + TxType: 0, // GAS + RevertFundRecipient: "", + } + eventDataBytes, _ := json.Marshal(eventData) + + event := &store.Event{ + EventID: "0xhash:0", + EventData: eventDataBytes, + } + + inbound, err := processor.buildInboundObservation(event) + require.NoError(t, err) + assert.Nil(t, inbound.RevertInstructions) + }) + + t.Run("falls back verification data to tx hash", func(t *testing.T) { + eventData := InboundObservation{ + SourceChain: "eip155:1", + VerificationData: "", + TxType: 0, + } + eventDataBytes, _ := json.Marshal(eventData) + + event := &store.Event{ + EventID: "0xhash:0", + EventData: eventDataBytes, + } + + inbound, err := processor.buildInboundObservation(event) + require.NoError(t, err) + assert.Equal(t, "0xhash", inbound.VerificationData) + }) + + t.Run("tx type mapping", func(t *testing.T) { + testCases := []struct { + txType uint + expected uexecutortypes.TxType + }{ + {0, uexecutortypes.TxType_GAS}, + {1, uexecutortypes.TxType_GAS_AND_PAYLOAD}, + {2, uexecutortypes.TxType_FUNDS}, + {3, uexecutortypes.TxType_FUNDS_AND_PAYLOAD}, + {99, uexecutortypes.TxType_UNSPECIFIED_TX}, // Unknown defaults to unspecified + } + + for _, tc := range testCases { + eventData := InboundObservation{ + SourceChain: "eip155:1", + TxType: tc.txType, + } + eventDataBytes, _ := json.Marshal(eventData) + + event := &store.Event{ + EventID: "0xabc:0", + EventData: eventDataBytes, + } + + inbound, err := processor.buildInboundObservation(event) + require.NoError(t, err) + assert.Equal(t, tc.expected, inbound.TxType, "TxType %d should map to %v", tc.txType, tc.expected) + } + }) +} + +func TestInboundHandleEvent(t *testing.T) { + ctx := context.Background() + + t.Run("construct failure returns error, event stays CONFIRMED", func(t *testing.T) { + database := newTestDB(t) + processor := NewInboundObservationEventProcessor(&fakeVoteSigner{txHash: "0xvote"}, database, zerolog.Nop()) + seedConfirmedEvent(t, database, "0xbad:0", store.EventTypeInbound, []byte("not json")) + + err := processor.HandleEvent(ctx, &store.Event{EventID: "0xbad:0", EventData: []byte("not json")}) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to build inbound observation") + }) + + t.Run("vote failure returns error", func(t *testing.T) { + database := newTestDB(t) + processor := NewInboundObservationEventProcessor(&fakeVoteSigner{err: fmt.Errorf("broadcast failed")}, database, zerolog.Nop()) + eventData, _ := json.Marshal(InboundObservation{SourceChain: "eip155:1", TxType: 0}) + + err := processor.HandleEvent(ctx, &store.Event{EventID: "0xin:0", EventData: eventData}) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to vote on inbound") + }) + + t.Run("successful vote marks event completed", func(t *testing.T) { + database := newTestDB(t) + signer := &fakeVoteSigner{txHash: "0xvote"} + processor := NewInboundObservationEventProcessor(signer, database, zerolog.Nop()) + eventData, _ := json.Marshal(InboundObservation{SourceChain: "eip155:1", TxType: 0}) + seedConfirmedEvent(t, database, "0xin:0", store.EventTypeInbound, eventData) + + err := processor.HandleEvent(ctx, &store.Event{EventID: "0xin:0", Type: store.EventTypeInbound, EventData: eventData}) + require.NoError(t, err) + assert.Equal(t, 1, signer.inboundVotes) + + rows, err := NewChainStore(database).UpdateEventStatus("0xin:0", store.StatusCompleted, store.StatusCompleted) + require.NoError(t, err) + assert.Equal(t, int64(1), rows) + }) +} diff --git a/universalClient/externalchains/common/outbound_observation_event_processor.go b/universalClient/externalchains/common/outbound_observation_event_processor.go new file mode 100644 index 00000000..8ba4ee29 --- /dev/null +++ b/universalClient/externalchains/common/outbound_observation_event_processor.go @@ -0,0 +1,119 @@ +package common + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/pushchain/push-chain-node/universalClient/db" + "github.com/pushchain/push-chain-node/universalClient/store" + uexecutortypes "github.com/pushchain/push-chain-node/x/uexecutor/types" + "github.com/rs/zerolog" +) + +// OutboundObservation is the outbound observation payload stored for OUTBOUND events +// Event structure: +// - txID at 1st indexed position (bytes32) +// - universalTxID at 2nd indexed position (bytes32) +type OutboundObservation struct { + TxID string `json:"tx_id"` // bytes32 hex-encoded (0x...) + UniversalTxID string `json:"universal_tx_id"` // bytes32 hex-encoded (0x...) + GasFeeUsed string `json:"gas_fee_used,omitempty"` // gas fee used in wei (decimal string) + // PC20 export only: wrapper token address deployed/minted on the destination + // at settlement (observed in the finalize event). Core uses it to flip the + // PC20 deploy flag; empty for non-PC20 settlements. + Pc20WrapperAddress string `json:"pc20_wrapper_address,omitempty"` +} + +// OutboundObservationEventProcessor handles OUTBOUND events: it builds the +// outbound observation from the stored event and votes it on Push chain. +type OutboundObservationEventProcessor struct { + signer VoteSigner + chainStore *ChainStore + logger zerolog.Logger +} + +// NewOutboundObservationEventProcessor creates the handler for OUTBOUND events. +func NewOutboundObservationEventProcessor( + signer VoteSigner, + database *db.DB, + logger zerolog.Logger, +) *OutboundObservationEventProcessor { + return &OutboundObservationEventProcessor{ + signer: signer, + chainStore: NewChainStore(database), + logger: logger.With().Str("component", "outbound_observation_event_processor").Logger(), + } +} + +// HandleEvent implements EventHandler for OUTBOUND events. +func (p *OutboundObservationEventProcessor) HandleEvent(ctx context.Context, event *store.Event) error { + p.logger.Debug(). + Str("event_id", event.EventID). + Msg("processing outbound event") + + // Parse outbound event data once + outboundData, err := p.parseOutboundEventData(event) + if err != nil { + return fmt.Errorf("failed to parse outbound event data: %w", err) + } + + // Build observation from parsed data + observation, err := p.buildOutboundObservation(event, outboundData) + if err != nil { + return fmt.Errorf("failed to build outbound observation: %w", err) + } + + // Vote on outbound + voteTxHash, err := p.signer.VoteOutbound(ctx, outboundData.TxID, outboundData.UniversalTxID, observation) + if err != nil { + return fmt.Errorf("failed to vote on outbound: %w", err) + } + + return markEventCompleted(p.chainStore, p.logger, event, voteTxHash) +} + +// parseOutboundEventData unmarshals event data into an OutboundObservation struct +func (p *OutboundObservationEventProcessor) parseOutboundEventData(event *store.Event) (*OutboundObservation, error) { + if event == nil { + return nil, fmt.Errorf("event is nil") + } + + if len(event.EventData) == 0 { + return nil, fmt.Errorf("event data is empty") + } + + var eventData OutboundObservation + if err := json.Unmarshal(event.EventData, &eventData); err != nil { + return nil, fmt.Errorf("failed to unmarshal event data: %w", err) + } + + if eventData.TxID == "" { + return nil, fmt.Errorf("tx_id not found in event data") + } + + if eventData.UniversalTxID == "" { + return nil, fmt.Errorf("universal_tx_id not found in event data") + } + + return &eventData, nil +} + +// buildOutboundObservation builds an OutboundObservation from event metadata and parsed outbound data +func (p *OutboundObservationEventProcessor) buildOutboundObservation(event *store.Event, outboundData *OutboundObservation) (*uexecutortypes.OutboundObservation, error) { + gasFeeUsed := "0" + if outboundData.GasFeeUsed != "" { + gasFeeUsed = outboundData.GasFeeUsed + } + + observation := &uexecutortypes.OutboundObservation{ + Success: true, + BlockHeight: event.BlockHeight, + TxHash: eventTxHash(event.EventID), + ErrorMsg: "", + GasFeeUsed: gasFeeUsed, + Pc20WrapperAddress: outboundData.Pc20WrapperAddress, + } + + return observation, nil +} diff --git a/universalClient/externalchains/common/outbound_observation_event_processor_test.go b/universalClient/externalchains/common/outbound_observation_event_processor_test.go new file mode 100644 index 00000000..af3db22c --- /dev/null +++ b/universalClient/externalchains/common/outbound_observation_event_processor_test.go @@ -0,0 +1,191 @@ +package common + +import ( + "context" + "encoding/json" + "fmt" + "testing" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/pushchain/push-chain-node/universalClient/store" +) + +func TestOutboundParseOutboundEventData(t *testing.T) { + processor := NewOutboundObservationEventProcessor(nil, nil, zerolog.Nop()) + + t.Run("nil event returns error", func(t *testing.T) { + data, err := processor.parseOutboundEventData(nil) + require.Error(t, err) + assert.Nil(t, data) + assert.Contains(t, err.Error(), "event is nil") + }) + + t.Run("empty event data returns error", func(t *testing.T) { + event := &store.Event{ + EventID: "test", + EventData: []byte{}, + } + data, err := processor.parseOutboundEventData(event) + require.Error(t, err) + assert.Nil(t, data) + assert.Contains(t, err.Error(), "event data is empty") + }) + + t.Run("valid outbound event extracts IDs and gas fee", func(t *testing.T) { + eventData := OutboundObservation{ + TxID: "0x1234", + UniversalTxID: "0xabcd", + GasFeeUsed: "42000000000000", + } + eventDataBytes, _ := json.Marshal(eventData) + + event := &store.Event{ + EventID: "test", + EventData: eventDataBytes, + } + + data, err := processor.parseOutboundEventData(event) + require.NoError(t, err) + assert.Equal(t, "0x1234", data.TxID) + assert.Equal(t, "0xabcd", data.UniversalTxID) + assert.Equal(t, "42000000000000", data.GasFeeUsed) + }) + + t.Run("missing tx_id returns error", func(t *testing.T) { + eventData := OutboundObservation{ + TxID: "", + UniversalTxID: "0xabcd", + } + eventDataBytes, _ := json.Marshal(eventData) + + event := &store.Event{ + EventID: "test", + EventData: eventDataBytes, + } + + data, err := processor.parseOutboundEventData(event) + require.Error(t, err) + assert.Nil(t, data) + assert.Contains(t, err.Error(), "tx_id not found") + }) + + t.Run("missing universal_tx_id returns error", func(t *testing.T) { + eventData := OutboundObservation{ + TxID: "0x1234", + UniversalTxID: "", + } + eventDataBytes, _ := json.Marshal(eventData) + + event := &store.Event{ + EventID: "test", + EventData: eventDataBytes, + } + + data, err := processor.parseOutboundEventData(event) + require.Error(t, err) + assert.Nil(t, data) + assert.Contains(t, err.Error(), "universal_tx_id not found") + }) +} + +func TestOutboundBuildOutboundObservation(t *testing.T) { + processor := NewOutboundObservationEventProcessor(nil, nil, zerolog.Nop()) + + t.Run("builds observation with gas fee from parsed data", func(t *testing.T) { + outboundData := &OutboundObservation{ + TxID: "0x1234", + UniversalTxID: "0xabcd", + GasFeeUsed: "42000000000000", + } + + event := &store.Event{ + EventID: "0xabc123:5", + BlockHeight: 12345, + } + + obs, err := processor.buildOutboundObservation(event, outboundData) + require.NoError(t, err) + require.NotNil(t, obs) + assert.True(t, obs.Success) + assert.Equal(t, uint64(12345), obs.BlockHeight) + assert.Equal(t, "0xabc123", obs.TxHash) + assert.Equal(t, "42000000000000", obs.GasFeeUsed) + }) + + t.Run("missing gas fee defaults to 0", func(t *testing.T) { + outboundData := &OutboundObservation{ + TxID: "0x1234", + UniversalTxID: "0xabcd", + } + + event := &store.Event{ + EventID: "0xabc123:5", + BlockHeight: 12345, + } + + obs, err := processor.buildOutboundObservation(event, outboundData) + require.NoError(t, err) + require.NotNil(t, obs) + assert.Equal(t, "0", obs.GasFeeUsed) + }) + + t.Run("handles base58 tx hash", func(t *testing.T) { + outboundData := &OutboundObservation{ + TxID: "0x1234", + UniversalTxID: "0xabcd", + } + + event := &store.Event{ + EventID: "2VfUX:0", // Base58 encoded + BlockHeight: 100, + } + + obs, err := processor.buildOutboundObservation(event, outboundData) + require.NoError(t, err) + require.NotNil(t, obs) + assert.True(t, len(obs.TxHash) >= 2) + assert.Equal(t, "0x", obs.TxHash[:2]) + }) +} + +func TestOutboundHandleEvent(t *testing.T) { + ctx := context.Background() + + t.Run("parse failure returns error", func(t *testing.T) { + database := newTestDB(t) + processor := NewOutboundObservationEventProcessor(&fakeVoteSigner{txHash: "0xvote"}, database, zerolog.Nop()) + + err := processor.HandleEvent(ctx, &store.Event{EventID: "0xbad:0", EventData: []byte("not json")}) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to parse outbound event data") + }) + + t.Run("vote failure returns error", func(t *testing.T) { + database := newTestDB(t) + processor := NewOutboundObservationEventProcessor(&fakeVoteSigner{err: fmt.Errorf("broadcast failed")}, database, zerolog.Nop()) + eventData, _ := json.Marshal(OutboundObservation{TxID: "0xtxid", UniversalTxID: "0xutxid"}) + + err := processor.HandleEvent(ctx, &store.Event{EventID: "0xout:0", EventData: eventData}) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to vote on outbound") + }) + + t.Run("successful vote marks event completed", func(t *testing.T) { + database := newTestDB(t) + signer := &fakeVoteSigner{txHash: "0xvote"} + processor := NewOutboundObservationEventProcessor(signer, database, zerolog.Nop()) + eventData, _ := json.Marshal(OutboundObservation{TxID: "0xtxid", UniversalTxID: "0xutxid"}) + seedConfirmedEvent(t, database, "0xout:0", store.EventTypeOutbound, eventData) + + err := processor.HandleEvent(ctx, &store.Event{EventID: "0xout:0", Type: store.EventTypeOutbound, EventData: eventData}) + require.NoError(t, err) + assert.Equal(t, 1, signer.outboundVotes) + + rows, err := NewChainStore(database).UpdateEventStatus("0xout:0", store.StatusCompleted, store.StatusCompleted) + require.NoError(t, err) + assert.Equal(t, int64(1), rows) + }) +} diff --git a/universalClient/externalchains/common/types.go b/universalClient/externalchains/common/types.go index f3b2317c..4628b1fc 100644 --- a/universalClient/externalchains/common/types.go +++ b/universalClient/externalchains/common/types.go @@ -2,11 +2,29 @@ package common import ( "context" + "fmt" "math/big" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" uetypes "github.com/pushchain/push-chain-node/x/uexecutor/types" ) +// EncodeUint256Result canonically encodes a balance/amount as abi.encode(uint256) +// so read results are byte-identical across validators and decodable by the +// requesting contract. The bounds check guards against a malicious RPC value +// that would not fit (FillBytes panics on overflow). +func EncodeUint256Result(v *big.Int) ([]byte, error) { + if v == nil { + v = big.NewInt(0) + } + if v.Sign() < 0 || v.BitLen() > 256 { + return nil, fmt.Errorf("value out of uint256 range") + } + out := make([]byte, 32) + v.FillBytes(out) + return out, nil +} + // ChainClient defines the interface for chain-specific implementations type ChainClient interface { // Start initializes and starts the chain client @@ -21,6 +39,11 @@ type ChainClient interface { // GetTxBuilder returns the TxBuilder for this chain // Returns an error if txBuilder is not supported for this chain (e.g., Push chain) GetTxBuilder() (TxBuilder, error) + + // GetReadRequestHandler returns the handler executing read requests + // destined for this chain + // Returns an error if reads are not available (e.g. client not started) + GetReadRequestHandler() (ReadRequestHandler, error) } // FundMigrationData contains the data needed to build a fund migration transaction. @@ -91,32 +114,16 @@ type TxBuilder interface { BroadcastFundMigrationTx(ctx context.Context, req *UnsignedSigningReq, data *FundMigrationData, signature []byte) (string, error) } -// UniversalTx Payload -type UniversalTx struct { - SourceChain string `json:"sourceChain"` - LogIndex uint `json:"logIndex"` - Sender string `json:"sender"` - Recipient string `json:"recipient"` - Token string `json:"bridgeToken"` - Amount string `json:"bridgeAmount"` // uint256 as decimal string - RawPayload string `json:"rawPayload,omitempty"` // hex-encoded raw payload bytes from source chain - VerificationData string `json:"verificationData"` - RevertFundRecipient string `json:"revertFundRecipient,omitempty"` - TxType uint `json:"txType"` // enum backing uint as decimal string - FromCEA bool `json:"fromCEA"` // true if inbound is initiated by a CEA +// ReadRequestHandler executes a read request on one destination chain. +// Consumed by the push watcher's read processor. +type ReadRequestHandler interface { + ExecuteRead(ctx context.Context, req *ucallbacktypes.ReadRequest) (*ucallbacktypes.ReadResult, error) } -// OutboundEvent represents an outbound observation event from the gateway contract -// Event structure: -// - txID at 1st indexed position (bytes32) -// - universalTxID at 2nd indexed position (bytes32) -type OutboundEvent struct { - TxID string `json:"tx_id"` // bytes32 hex-encoded (0x...) - UniversalTxID string `json:"universal_tx_id"` // bytes32 hex-encoded (0x...) - GasFeeUsed string `json:"gas_fee_used,omitempty"` // gas fee used in wei (decimal string) - // PC20 export only: wrapper token address deployed/minted on the destination - // at settlement (observed in the finalize event). Core uses it to flip the - // PC20 deploy flag; empty for non-PC20 settlements. - Pc20WrapperAddress string `json:"pc20_wrapper_address,omitempty"` +// NewReadErrorResult builds an ERROR observation. ResultData stays empty so every +// validator voting ERROR converges on the same ballot regardless of local error +// text; core's ReadResult has no error field for that reason, so err is logged by +// the caller, not carried on the vote. +func NewReadErrorResult(err error) *ucallbacktypes.ReadResult { + return &ucallbacktypes.ReadResult{Status: ucallbacktypes.ReadStatus_READ_STATUS_ERROR} } - diff --git a/universalClient/externalchains/evm/client.go b/universalClient/externalchains/evm/client.go index a9cf0c67..2b2af36a 100644 --- a/universalClient/externalchains/evm/client.go +++ b/universalClient/externalchains/evm/client.go @@ -14,6 +14,7 @@ import ( "github.com/pushchain/push-chain-node/universalClient/db" "github.com/pushchain/push-chain-node/universalClient/externalchains/common" "github.com/pushchain/push-chain-node/universalClient/pushsigner" + "github.com/pushchain/push-chain-node/universalClient/store" uregistrytypes "github.com/pushchain/push-chain-node/x/uregistry/types" ) @@ -86,16 +87,14 @@ func NewClient( // Initialize components that don't require RPC client if pushSigner != nil { - inboundEnabled := config.Enabled != nil && config.Enabled.IsInboundEnabled - outboundEnabled := config.Enabled != nil && config.Enabled.IsOutboundEnabled - client.eventProcessor = common.NewEventProcessor( - pushSigner, - database, - chainIDStr, - inboundEnabled, - outboundEnabled, - log, - ) + ep := common.NewEventProcessor(database, chainIDStr, log) + if config.Enabled != nil && config.Enabled.IsInboundEnabled { + ep.RegisterHandler(store.EventTypeInbound, common.NewInboundObservationEventProcessor(pushSigner, database, log)) + } + if config.Enabled != nil && config.Enabled.IsOutboundEnabled { + ep.RegisterHandler(store.EventTypeOutbound, common.NewOutboundObservationEventProcessor(pushSigner, database, log)) + } + client.eventProcessor = ep } return client, nil @@ -199,6 +198,14 @@ func (c *Client) GetTxBuilder() (common.TxBuilder, error) { return c.txBuilder, nil } +// GetReadRequestHandler returns the read request handler for this chain +func (c *Client) GetReadRequestHandler() (common.ReadRequestHandler, error) { + if c.rpcClient == nil { + return nil, fmt.Errorf("read handler not available for chain %s (client not started)", c.chainIDStr) + } + return c, nil +} + // initializeComponents creates all components that require the RPC client func (c *Client) initializeComponents() error { // Create event listener if gateway is configured diff --git a/universalClient/externalchains/evm/event_confirmer.go b/universalClient/externalchains/evm/event_confirmer.go index 45cabc08..b4c73a83 100644 --- a/universalClient/externalchains/evm/event_confirmer.go +++ b/universalClient/externalchains/evm/event_confirmer.go @@ -181,7 +181,7 @@ func (ec *EventConfirmer) processPendingEvents(ctx context.Context) error { gasFeeUsed := new(big.Int).Mul(gasUsed, gasPrice).String() // Unmarshal, set GasFeeUsed, re-marshal - var outboundEvent chaincommon.OutboundEvent + var outboundEvent chaincommon.OutboundObservation if unmarshalErr := json.Unmarshal(event.EventData, &outboundEvent); unmarshalErr != nil { ec.logger.Error(). Err(unmarshalErr). diff --git a/universalClient/externalchains/evm/event_confirmer_test.go b/universalClient/externalchains/evm/event_confirmer_test.go index 022812cb..55ae7f51 100644 --- a/universalClient/externalchains/evm/event_confirmer_test.go +++ b/universalClient/externalchains/evm/event_confirmer_test.go @@ -313,7 +313,7 @@ func TestEventConfirmer_UpdateStatusAndEventData_WithDB(t *testing.T) { _, memDB := newTestEventConfirmerWithDB(t) cs := common.NewChainStore(memDB) - outbound := common.OutboundEvent{ + outbound := common.OutboundObservation{ TxID: "0xtx1", UniversalTxID: "0xuni1", } @@ -347,7 +347,7 @@ func TestEventConfirmer_UpdateStatusAndEventData_WithDB(t *testing.T) { require.Len(t, confirmed, 1) assert.Equal(t, "0xoutbound1:0", confirmed[0].EventID) - var stored common.OutboundEvent + var stored common.OutboundObservation require.NoError(t, json.Unmarshal(confirmed[0].EventData, &stored)) assert.Equal(t, "123456789", stored.GasFeeUsed) } diff --git a/universalClient/externalchains/evm/event_parser.go b/universalClient/externalchains/evm/event_parser.go index 3d44d470..a603f8ad 100644 --- a/universalClient/externalchains/evm/event_parser.go +++ b/universalClient/externalchains/evm/event_parser.go @@ -125,7 +125,7 @@ func parseOutboundObservationEvent(log *types.Log, eventType string, logger zero } // Create OutboundEvent payload - payload := common.OutboundEvent{ + payload := common.OutboundObservation{ TxID: txID, UniversalTxID: universalTxID, Pc20WrapperAddress: wrapperAddr, @@ -168,7 +168,7 @@ func parseUniversalTxEvent(event *store.Event, log *types.Log, chainID string, l return } - payload := common.UniversalTx{ + payload := common.InboundObservation{ SourceChain: chainID, Sender: ethcommon.BytesToAddress(log.Topics[1].Bytes()).Hex(), Recipient: ethcommon.BytesToAddress(log.Topics[2].Bytes()).Hex(), @@ -215,7 +215,7 @@ func readWord(data []byte, i int) []byte { // decodePayload reads the raw payload bytes at the given offset and stores the hex string. // The core validator will decode the universal payload from these raw bytes. -func decodePayload(data []byte, dataOffset uint64, payload *common.UniversalTx, logger zerolog.Logger) { +func decodePayload(data []byte, dataOffset uint64, payload *common.InboundObservation, logger zerolog.Logger) { if dataOffset < uint64(32*5) { return } @@ -240,7 +240,7 @@ func decodeSignatureData(data []byte, w []byte, minOffset uint64) string { } // finalizeEvent marshals the payload and sets confirmation type on the event. -func finalizeEvent(event *store.Event, payload *common.UniversalTx, logger zerolog.Logger) { +func finalizeEvent(event *store.Event, payload *common.InboundObservation, logger zerolog.Logger) { if b, err := json.Marshal(payload); err == nil { event.EventData = b } else { @@ -266,7 +266,7 @@ UniversalTx Event (V2 - upgraded chains): - signatureData (bytes) — Word 5 (offset) - fromCEA (bool) — Word 6 */ -func parseUniversalTx(event *store.Event, log *types.Log, dataOffset uint64, payload *common.UniversalTx, logger zerolog.Logger) { +func parseUniversalTx(event *store.Event, log *types.Log, dataOffset uint64, payload *common.InboundObservation, logger zerolog.Logger) { data := log.Data decodePayload(data, dataOffset, payload, logger) diff --git a/universalClient/externalchains/evm/event_parser_test.go b/universalClient/externalchains/evm/event_parser_test.go index 9fb77e1e..88dbc878 100644 --- a/universalClient/externalchains/evm/event_parser_test.go +++ b/universalClient/externalchains/evm/event_parser_test.go @@ -337,7 +337,7 @@ func TestParseOutboundObservation_PC20Wrapper(t *testing.T) { wrapperOf := func(t *testing.T, e *store.Event) string { t.Helper() - var ob common.OutboundEvent + var ob common.OutboundObservation require.NoError(t, json.Unmarshal(e.EventData, &ob)) return ob.Pc20WrapperAddress } @@ -544,21 +544,21 @@ func TestDecodePayload(t *testing.T) { big.NewInt(int64(len(inner))).FillBytes(data[160:192]) copy(data[192:196], inner) - payload := &common.UniversalTx{} + payload := &common.InboundObservation{} decodePayload(data, 160, payload, logger) assert.Equal(t, "0xdeadbeef", payload.RawPayload) }) t.Run("offset too small is ignored", func(t *testing.T) { data := make([]byte, 256) - payload := &common.UniversalTx{} + payload := &common.InboundObservation{} decodePayload(data, 32, payload, logger) // < 32*5 assert.Empty(t, payload.RawPayload) }) t.Run("offset zero is ignored", func(t *testing.T) { data := make([]byte, 256) - payload := &common.UniversalTx{} + payload := &common.InboundObservation{} decodePayload(data, 0, payload, logger) assert.Empty(t, payload.RawPayload) }) @@ -566,7 +566,7 @@ func TestDecodePayload(t *testing.T) { t.Run("readDynamicBytes fails gracefully", func(t *testing.T) { // Data is too short for the length word at the offset data := make([]byte, 168) // offset 160 + only 8 bytes; need 32 for length - payload := &common.UniversalTx{} + payload := &common.InboundObservation{} decodePayload(data, 160, payload, logger) assert.Empty(t, payload.RawPayload) }) @@ -634,13 +634,13 @@ func TestFinalizeEvent(t *testing.T) { t.Run("txType 0 sets FAST confirmation", func(t *testing.T) { event := &store.Event{} - payload := &common.UniversalTx{TxType: 0, Sender: "0xabc"} + payload := &common.InboundObservation{TxType: 0, Sender: "0xabc"} finalizeEvent(event, payload, logger) assert.Equal(t, store.ConfirmationFast, event.ConfirmationType) assert.NotNil(t, event.EventData) - var decoded common.UniversalTx + var decoded common.InboundObservation err := json.Unmarshal(event.EventData, &decoded) require.NoError(t, err) assert.Equal(t, "0xabc", decoded.Sender) @@ -648,7 +648,7 @@ func TestFinalizeEvent(t *testing.T) { t.Run("txType 1 sets FAST confirmation", func(t *testing.T) { event := &store.Event{} - payload := &common.UniversalTx{TxType: 1} + payload := &common.InboundObservation{TxType: 1} finalizeEvent(event, payload, logger) assert.Equal(t, store.ConfirmationFast, event.ConfirmationType) @@ -656,7 +656,7 @@ func TestFinalizeEvent(t *testing.T) { t.Run("txType 2 sets STANDARD confirmation", func(t *testing.T) { event := &store.Event{} - payload := &common.UniversalTx{TxType: 2} + payload := &common.InboundObservation{TxType: 2} finalizeEvent(event, payload, logger) assert.Equal(t, store.ConfirmationStandard, event.ConfirmationType) @@ -664,7 +664,7 @@ func TestFinalizeEvent(t *testing.T) { t.Run("txType 3 sets STANDARD confirmation", func(t *testing.T) { event := &store.Event{} - payload := &common.UniversalTx{TxType: 3} + payload := &common.InboundObservation{TxType: 3} finalizeEvent(event, payload, logger) assert.Equal(t, store.ConfirmationStandard, event.ConfirmationType) @@ -672,7 +672,7 @@ func TestFinalizeEvent(t *testing.T) { t.Run("high txType sets STANDARD confirmation", func(t *testing.T) { event := &store.Event{} - payload := &common.UniversalTx{TxType: 255} + payload := &common.InboundObservation{TxType: 255} finalizeEvent(event, payload, logger) assert.Equal(t, store.ConfirmationStandard, event.ConfirmationType) @@ -680,7 +680,7 @@ func TestFinalizeEvent(t *testing.T) { t.Run("event data is valid JSON", func(t *testing.T) { event := &store.Event{} - payload := &common.UniversalTx{ + payload := &common.InboundObservation{ SourceChain: "eip155:1", Sender: "0xsender", Recipient: "0xrecipient", @@ -690,7 +690,7 @@ func TestFinalizeEvent(t *testing.T) { } finalizeEvent(event, payload, logger) - var decoded common.UniversalTx + var decoded common.InboundObservation err := json.Unmarshal(event.EventData, &decoded) require.NoError(t, err) assert.Equal(t, "eip155:1", decoded.SourceChain) diff --git a/universalClient/externalchains/evm/read_envelope.go b/universalClient/externalchains/evm/read_envelope.go new file mode 100644 index 00000000..428ce66c --- /dev/null +++ b/universalClient/externalchains/evm/read_envelope.go @@ -0,0 +1,120 @@ +package evm + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" + ethcommon "github.com/ethereum/go-ethereum/common" +) + +// evmQueryType mirrors the EvmQueryEnvelope enum from the read spec. +type evmQueryType uint8 + +const ( + evmQueryAccountBalance evmQueryType = 0 + evmQueryContractCall evmQueryType = 1 + evmQueryStorageSlot evmQueryType = 2 +) + +// evmBlockRefType mirrors the EvmBlockRefType enum. Only AT_NUMBER exists in v1. +type evmBlockRefType uint8 + +const evmBlockRefAtNumber evmBlockRefType = 0 + +// evmQueryEnvelope is the decoded abi.encode(EvmQueryEnvelope) query. +type evmQueryEnvelope struct { + QueryType evmQueryType + RefType evmBlockRefType + BlockNumber uint64 + Payload []byte +} + +var ( + evmEnvelopeArgs = mustReadArgs(abi.ArgumentMarshaling{Type: "tuple", Components: []abi.ArgumentMarshaling{ + {Name: "queryType", Type: "uint8"}, + {Name: "blockRef", Type: "tuple", Components: []abi.ArgumentMarshaling{ + {Name: "refType", Type: "uint8"}, + {Name: "blockNumber", Type: "uint64"}, + }}, + {Name: "payload", Type: "bytes"}, + }}) + + addressArgs = mustReadArgs(abi.ArgumentMarshaling{Type: "address"}) + addressBytesArgs = mustReadArgs(abi.ArgumentMarshaling{Type: "address"}, abi.ArgumentMarshaling{Type: "bytes"}) + addressBytes32Args = mustReadArgs(abi.ArgumentMarshaling{Type: "address"}, abi.ArgumentMarshaling{Type: "bytes32"}) +) + +func mustReadArgs(marshalings ...abi.ArgumentMarshaling) abi.Arguments { + args := make(abi.Arguments, 0, len(marshalings)) + for i, m := range marshalings { + if m.Name == "" { + m.Name = fmt.Sprintf("arg%d", i) + } + typ, err := abi.NewType(m.Type, "", m.Components) + if err != nil { + panic(fmt.Sprintf("evm: invalid abi type %q: %v", m.Type, err)) + } + args = append(args, abi.Argument{Name: m.Name, Type: typ}) + } + return args +} + +type rawEvmEnvelope struct { + QueryType uint8 + BlockRef struct { + RefType uint8 + BlockNumber uint64 + } + Payload []byte +} + +// decodeEvmQueryEnvelope decodes ReadSpec.query for eip155 chains. +func decodeEvmQueryEnvelope(query []byte) (*evmQueryEnvelope, error) { + vals, err := evmEnvelopeArgs.Unpack(query) + if err != nil { + return nil, fmt.Errorf("failed to unpack EvmQueryEnvelope: %w", err) + } + raw := *abi.ConvertType(vals[0], new(rawEvmEnvelope)).(*rawEvmEnvelope) + + env := &evmQueryEnvelope{ + QueryType: evmQueryType(raw.QueryType), + RefType: evmBlockRefType(raw.BlockRef.RefType), + BlockNumber: raw.BlockRef.BlockNumber, + Payload: raw.Payload, + } + if env.QueryType > evmQueryStorageSlot { + return nil, fmt.Errorf("unknown EvmQueryType %d", env.QueryType) + } + if env.RefType != evmBlockRefAtNumber { + return nil, fmt.Errorf("unsupported EvmBlockRefType %d", env.RefType) + } + return env, nil +} + +// decodeAccountBalancePayload decodes abi.encode(address target). +func decodeAccountBalancePayload(payload []byte) (ethcommon.Address, error) { + vals, err := addressArgs.Unpack(payload) + if err != nil { + return ethcommon.Address{}, fmt.Errorf("failed to unpack AccountBalance payload: %w", err) + } + return vals[0].(ethcommon.Address), nil +} + +// decodeContractCallPayload decodes abi.encode(address target, bytes callData). +func decodeContractCallPayload(payload []byte) (ethcommon.Address, []byte, error) { + vals, err := addressBytesArgs.Unpack(payload) + if err != nil { + return ethcommon.Address{}, nil, fmt.Errorf("failed to unpack ContractCall payload: %w", err) + } + return vals[0].(ethcommon.Address), vals[1].([]byte), nil +} + +// decodeStorageSlotPayload decodes abi.encode(address contractAddr, bytes32 slot). +func decodeStorageSlotPayload(payload []byte) (ethcommon.Address, ethcommon.Hash, error) { + vals, err := addressBytes32Args.Unpack(payload) + if err != nil { + return ethcommon.Address{}, ethcommon.Hash{}, fmt.Errorf("failed to unpack StorageSlot payload: %w", err) + } + slot := vals[1].([32]byte) + return vals[0].(ethcommon.Address), ethcommon.Hash(slot), nil +} diff --git a/universalClient/externalchains/evm/read_envelope_test.go b/universalClient/externalchains/evm/read_envelope_test.go new file mode 100644 index 00000000..5d07e7d4 --- /dev/null +++ b/universalClient/externalchains/evm/read_envelope_test.go @@ -0,0 +1,72 @@ +package evm + +import ( + "testing" + + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func packEvmEnvelope(t *testing.T, queryType, refType uint8, blockNumber uint64, payload []byte) []byte { + t.Helper() + data, err := evmEnvelopeArgs.Pack(rawEvmEnvelope{ + QueryType: queryType, + BlockRef: struct { + RefType uint8 + BlockNumber uint64 + }{refType, blockNumber}, + Payload: payload, + }) + require.NoError(t, err) + return data +} + +func TestDecodeEvmQueryEnvelope(t *testing.T) { + target := ethcommon.HexToAddress("0x1111111111111111111111111111111111111111") + payload, err := addressArgs.Pack(target) + require.NoError(t, err) + + env, err := decodeEvmQueryEnvelope(packEvmEnvelope(t, uint8(evmQueryAccountBalance), 0, 1234, payload)) + require.NoError(t, err) + assert.Equal(t, evmQueryAccountBalance, env.QueryType) + assert.Equal(t, evmBlockRefAtNumber, env.RefType) + assert.Equal(t, uint64(1234), env.BlockNumber) + + decoded, err := decodeAccountBalancePayload(env.Payload) + require.NoError(t, err) + assert.Equal(t, target, decoded) +} + +func TestDecodeEvmQueryEnvelope_Invalid(t *testing.T) { + _, err := decodeEvmQueryEnvelope([]byte{0x01, 0x02}) + assert.Error(t, err) + + // unknown query type + _, err = decodeEvmQueryEnvelope(packEvmEnvelope(t, 9, 0, 0, nil)) + assert.Error(t, err) + + // unknown block ref type + _, err = decodeEvmQueryEnvelope(packEvmEnvelope(t, 0, 7, 0, nil)) + assert.Error(t, err) +} + +func TestDecodeEvmPayloads(t *testing.T) { + token := ethcommon.HexToAddress("0x2222222222222222222222222222222222222222") + + callData := []byte{0xde, 0xad, 0xbe, 0xef} + callPayload, err := addressBytesArgs.Pack(token, callData) + require.NoError(t, err) + gotTarget, gotData, err := decodeContractCallPayload(callPayload) + require.NoError(t, err) + assert.Equal(t, token, gotTarget) + assert.Equal(t, callData, gotData) + + slot := [32]byte{0x0a} + slotPayload, err := addressBytes32Args.Pack(token, slot) + require.NoError(t, err) + gotAddr, gotSlot, err := decodeStorageSlotPayload(slotPayload) + require.NoError(t, err) + assert.Equal(t, token, gotAddr) + assert.Equal(t, ethcommon.Hash(slot), gotSlot) +} diff --git a/universalClient/externalchains/evm/read_executor.go b/universalClient/externalchains/evm/read_executor.go new file mode 100644 index 00000000..c2f63acb --- /dev/null +++ b/universalClient/externalchains/evm/read_executor.go @@ -0,0 +1,130 @@ +package evm + +import ( + "context" + "errors" + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/rpc" + + "github.com/pushchain/push-chain-node/universalClient/externalchains/common" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +// ExecuteRead implements common.ChainReader for EVM chains. +// All validators must produce byte-identical results, so every query runs at the +// height pinned in the request; execution is gated until that height has +// min_confirmations confirmations so a reorg cannot invalidate the read. +func (c *Client) ExecuteRead(ctx context.Context, req *ucallbacktypes.ReadRequest) (*ucallbacktypes.ReadResult, error) { + env, err := decodeEvmQueryEnvelope(req.Query) + if err != nil { + return common.NewReadErrorResult(err), nil + } + + height := req.DestinationBlockHeight + if height == 0 { + height = env.BlockNumber + } + if height == 0 { + return common.NewReadErrorResult(fmt.Errorf("read request has no target height")), nil + } + + if err := c.gateHeightConfirmed(ctx, height, uint64(req.MinConfirmations)); err != nil { + return nil, err + } + blockNum := new(big.Int).SetUint64(height) + + header, err := c.rpcClient.GetHeaderByNumber(ctx, blockNum) + if err != nil { + return nil, fmt.Errorf("failed to fetch header at %d: %w", height, err) + } + + var resultData []byte + switch env.QueryType { + case evmQueryAccountBalance: + target, decErr := decodeAccountBalancePayload(env.Payload) + if decErr != nil { + return common.NewReadErrorResult(decErr), nil + } + balance, rpcErr := c.rpcClient.GetBalanceAt(ctx, target, blockNum) + if rpcErr != nil { + return nil, rpcErr + } + resultData, err = common.EncodeUint256Result(balance) + + case evmQueryContractCall: + target, callData, decErr := decodeContractCallPayload(env.Payload) + if decErr != nil { + return common.NewReadErrorResult(decErr), nil + } + ret, rpcErr := c.rpcClient.CallContract(ctx, target, callData, blockNum) + if rpcErr != nil { + // Only a genuine execution revert is deterministic at the pinned + // height and safe to vote. A transport error or a node-state error + // (e.g. missing trie node on a pruned node) is not deterministic and + // must be retried, never voted. + if isExecutionRevert(rpcErr) { + return common.NewReadErrorResult(rpcErr), nil + } + return nil, rpcErr + } + resultData = ret + + case evmQueryStorageSlot: + target, slot, decErr := decodeStorageSlotPayload(env.Payload) + if decErr != nil { + return common.NewReadErrorResult(decErr), nil + } + value, rpcErr := c.rpcClient.GetStorageAt(ctx, target, slot, blockNum) + if rpcErr != nil { + return nil, rpcErr + } + var slotValue [32]byte + copy(slotValue[32-min(len(value), 32):], value) + resultData = slotValue[:] + + default: + return common.NewReadErrorResult(fmt.Errorf("unknown EvmQueryType %d", env.QueryType)), nil + } + if err != nil { + return common.NewReadErrorResult(err), nil + } + + return &ucallbacktypes.ReadResult{ + Status: ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, + ResultData: resultData, + ObservedBlockHeight: height, + ObservedBlockHash: header.Hash().Bytes(), + }, nil +} + +// isExecutionRevert reports whether an eth_call error is a deterministic EVM +// revert (the node executed the call and it reverted) rather than a transient +// transport or node-state failure. Only a revert is safe to vote as ERROR. +func isExecutionRevert(err error) bool { + var dataErr rpc.DataError + if errors.As(err, &dataErr) && dataErr.ErrorData() != nil { + return true + } + var rpcErr rpc.Error + if errors.As(err, &rpcErr) && rpcErr.ErrorCode() == 3 { + return true + } + return strings.Contains(strings.ToLower(err.Error()), "execution reverted") +} + +// gateHeightConfirmed blocks execution until the target height has at least +// minConfirmations confirmations. An error is transient: the processor keeps +// the event CONFIRMED and retries next tick. +func (c *Client) gateHeightConfirmed(ctx context.Context, height, minConfirmations uint64) error { + latest, err := c.rpcClient.GetLatestBlock(ctx) + if err != nil { + return fmt.Errorf("failed to get latest block: %w", err) + } + if latest < height+minConfirmations { + return fmt.Errorf("height %d needs %d confirmations, chain at %d; not final yet", height, minConfirmations, latest) + } + return nil +} diff --git a/universalClient/externalchains/evm/read_executor_test.go b/universalClient/externalchains/evm/read_executor_test.go new file mode 100644 index 00000000..a8928fc9 --- /dev/null +++ b/universalClient/externalchains/evm/read_executor_test.go @@ -0,0 +1,315 @@ +package evm + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "net/http" + "net/http/httptest" + "testing" + + ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +// fakeHeader is a minimal valid block header JSON accepted by types.Header. +func fakeHeader(number uint64) map[string]any { + zeroHash := "0x0000000000000000000000000000000000000000000000000000000000000000" + return map[string]any{ + "parentHash": zeroHash, + "sha3Uncles": zeroHash, + "miner": "0x0000000000000000000000000000000000000000", + "stateRoot": zeroHash, + "transactionsRoot": zeroHash, + "receiptsRoot": zeroHash, + "logsBloom": "0x" + fmt.Sprintf("%0512x", 0), + "difficulty": "0x0", + "number": fmt.Sprintf("0x%x", number), + "gasLimit": "0x0", + "gasUsed": "0x0", + "timestamp": "0x0", + "extraData": "0x", + "mixHash": zeroHash, + "nonce": "0x0000000000000000", + } +} + +type rpcFault struct { + code int + message string +} + +// newReadTestClient spins up a JSON-RPC server answering from results/faults +// keyed by method name, and returns a Client wired to it. +func newReadTestClient(t *testing.T, results map[string]any, faults map[string]rpcFault) *Client { + t.Helper() + + // every read is gated on the chain tip; default to a comfortably deep chain + // unless the test overrides eth_blockNumber + if results != nil { + if _, ok := results["eth_blockNumber"]; !ok { + if _, ok := faults["eth_blockNumber"]; !ok { + results["eth_blockNumber"] = "0x1000" + } + } + } + + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var req struct { + ID json.RawMessage `json:"id"` + Method string `json:"method"` + } + require.NoError(t, json.NewDecoder(r.Body).Decode(&req)) + + resp := map[string]any{"jsonrpc": "2.0", "id": json.RawMessage(req.ID)} + if fault, ok := faults[req.Method]; ok { + resp["error"] = map[string]any{"code": fault.code, "message": fault.message} + } else if result, ok := results[req.Method]; ok { + resp["result"] = result + } else { + t.Errorf("unexpected RPC method %s", req.Method) + resp["error"] = map[string]any{"code": -32601, "message": "method not found"} + } + require.NoError(t, json.NewEncoder(w).Encode(resp)) + })) + t.Cleanup(srv.Close) + + ethClient, err := ethclient.Dial(srv.URL) + require.NoError(t, err) + t.Cleanup(ethClient.Close) + + return &Client{ + logger: zerolog.Nop(), + rpcClient: &RPCClient{clients: []*ethclient.Client{ethClient}, logger: zerolog.Nop()}, + } +} + +func evmReadRequest(t *testing.T, queryType uint8, blockNumber uint64, payload []byte) *ucallbacktypes.ReadRequest { + t.Helper() + return &ucallbacktypes.ReadRequest{ + RequestId: "0xreq1", + DestinationChain: "eip155:11155111", + Query: packEvmEnvelope(t, queryType, 0, blockNumber, payload), + MinConfirmations: 1, + DestinationBlockHeight: 100, + } +} + +func TestExecuteRead_AccountBalance(t *testing.T) { + target := ethcommon.HexToAddress("0x1111111111111111111111111111111111111111") + payload, err := addressArgs.Pack(target) + require.NoError(t, err) + + client := newReadTestClient(t, map[string]any{ + "eth_getBlockByNumber": fakeHeader(100), + "eth_getBalance": "0xf4240", // 1_000_000 + }, nil) + + result, err := client.ExecuteRead(context.Background(), evmReadRequest(t, uint8(evmQueryAccountBalance), 0, payload)) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, result.Status) + assert.Equal(t, big.NewInt(1_000_000), new(big.Int).SetBytes(result.ResultData)) + assert.Equal(t, uint64(100), result.ObservedBlockHeight) + assert.Len(t, result.ObservedBlockHash, 32) +} + +func TestExecuteRead_ContractCall(t *testing.T) { + target := ethcommon.HexToAddress("0x2222222222222222222222222222222222222222") + payload, err := addressBytesArgs.Pack(target, []byte{0xde, 0xad}) + require.NoError(t, err) + + t.Run("returns raw returndata", func(t *testing.T) { + client := newReadTestClient(t, map[string]any{ + "eth_getBlockByNumber": fakeHeader(100), + "eth_call": "0xcafebabe", + }, nil) + + result, err := client.ExecuteRead(context.Background(), evmReadRequest(t, uint8(evmQueryContractCall), 0, payload)) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, result.Status) + assert.Equal(t, []byte{0xca, 0xfe, 0xba, 0xbe}, result.ResultData) + }) + + t.Run("revert is a votable ERROR observation", func(t *testing.T) { + client := newReadTestClient(t, map[string]any{ + "eth_getBlockByNumber": fakeHeader(100), + }, map[string]rpcFault{ + "eth_call": {code: 3, message: "execution reverted"}, + }) + + result, err := client.ExecuteRead(context.Background(), evmReadRequest(t, uint8(evmQueryContractCall), 0, payload)) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + assert.Empty(t, result.ResultData) + }) + + t.Run("non-revert rpc error is transient, not voted", func(t *testing.T) { + // a pruned/unsynced node (missing trie node) is node-specific, not a + // deterministic revert; it must retry, never produce an ERROR vote + client := newReadTestClient(t, map[string]any{ + "eth_getBlockByNumber": fakeHeader(100), + }, map[string]rpcFault{ + "eth_call": {code: -32000, message: "missing trie node"}, + }) + + result, err := client.ExecuteRead(context.Background(), evmReadRequest(t, uint8(evmQueryContractCall), 0, payload)) + require.Error(t, err) + assert.Nil(t, result) + }) +} + +func TestExecuteRead_StorageSlot(t *testing.T) { + target := ethcommon.HexToAddress("0x2222222222222222222222222222222222222222") + payload, err := addressBytes32Args.Pack(target, [32]byte{0x01}) + require.NoError(t, err) + + client := newReadTestClient(t, map[string]any{ + "eth_getBlockByNumber": fakeHeader(100), + "eth_getStorageAt": "0x" + fmt.Sprintf("%064x", 7), + }, nil) + + result, err := client.ExecuteRead(context.Background(), evmReadRequest(t, uint8(evmQueryStorageSlot), 0, payload)) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, result.Status) + require.Len(t, result.ResultData, 32) + assert.Equal(t, big.NewInt(7), new(big.Int).SetBytes(result.ResultData)) +} + +func TestExecuteRead_InvalidEnvelope(t *testing.T) { + client := newReadTestClient(t, nil, nil) + + result, err := client.ExecuteRead(context.Background(), &ucallbacktypes.ReadRequest{ + RequestId: "0xreq1", + Query: []byte{0x01, 0x02}, + DestinationBlockHeight: 100, + }) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) +} + +func TestExecuteRead_RPCFailureIsTransient(t *testing.T) { + target := ethcommon.HexToAddress("0x1111111111111111111111111111111111111111") + payload, err := addressArgs.Pack(target) + require.NoError(t, err) + + client := newReadTestClient(t, map[string]any{}, map[string]rpcFault{ + "eth_getBlockByNumber": {code: -32000, message: "node is syncing"}, + }) + + result, err := client.ExecuteRead(context.Background(), evmReadRequest(t, uint8(evmQueryAccountBalance), 0, payload)) + require.Error(t, err) + assert.Nil(t, result) +} + +func TestExecuteRead_PrunedStateIsTransient(t *testing.T) { + // A pruned node can serve the header but not old state. This is node-specific, + // not deterministic (an archive node returns the real value), so it must + // retry/abstain, never produce an ERROR vote — otherwise a pruned majority + // could wrongly quorum an ERROR for an address that has a balance. + t.Run("account balance", func(t *testing.T) { + target := ethcommon.HexToAddress("0x1111111111111111111111111111111111111111") + payload, err := addressArgs.Pack(target) + require.NoError(t, err) + + client := newReadTestClient(t, map[string]any{ + "eth_getBlockByNumber": fakeHeader(100), + }, map[string]rpcFault{ + "eth_getBalance": {code: -32000, message: "missing trie node"}, + }) + + result, err := client.ExecuteRead(context.Background(), evmReadRequest(t, uint8(evmQueryAccountBalance), 0, payload)) + require.Error(t, err) + assert.Nil(t, result) + }) + + t.Run("storage slot", func(t *testing.T) { + target := ethcommon.HexToAddress("0x2222222222222222222222222222222222222222") + payload, err := addressBytes32Args.Pack(target, [32]byte{0x01}) + require.NoError(t, err) + + client := newReadTestClient(t, map[string]any{ + "eth_getBlockByNumber": fakeHeader(100), + }, map[string]rpcFault{ + "eth_getStorageAt": {code: -32000, message: "missing trie node"}, + }) + + result, err := client.ExecuteRead(context.Background(), evmReadRequest(t, uint8(evmQueryStorageSlot), 0, payload)) + require.Error(t, err) + assert.Nil(t, result) + }) +} + +func TestExecuteRead_EnvelopeBlockNumberUsedWhenNotPinned(t *testing.T) { + target := ethcommon.HexToAddress("0x1111111111111111111111111111111111111111") + payload, err := addressArgs.Pack(target) + require.NoError(t, err) + + client := newReadTestClient(t, map[string]any{ + "eth_getBlockByNumber": fakeHeader(55), + "eth_getBalance": "0x1", + }, nil) + + req := evmReadRequest(t, uint8(evmQueryAccountBalance), 55, payload) + req.DestinationBlockHeight = 0 // client-provided height in the envelope + + result, err := client.ExecuteRead(context.Background(), req) + require.NoError(t, err) + assert.Equal(t, uint64(55), result.ObservedBlockHeight) +} + +func TestExecuteRead_MissingHeightIsVotableError(t *testing.T) { + target := ethcommon.HexToAddress("0x1111111111111111111111111111111111111111") + payload, err := addressArgs.Pack(target) + require.NoError(t, err) + + client := newReadTestClient(t, nil, nil) + + req := evmReadRequest(t, uint8(evmQueryAccountBalance), 0, payload) + req.DestinationBlockHeight = 0 + + result, err := client.ExecuteRead(context.Background(), req) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) +} + +func TestExecuteRead_ConfirmationGate(t *testing.T) { + target := ethcommon.HexToAddress("0x1111111111111111111111111111111111111111") + payload, err := addressArgs.Pack(target) + require.NoError(t, err) + + t.Run("height not deep enough is transient", func(t *testing.T) { + client := newReadTestClient(t, map[string]any{ + "eth_blockNumber": "0x64", // 100 + }, nil) + + req := evmReadRequest(t, uint8(evmQueryAccountBalance), 0, payload) + req.DestinationBlockHeight = 100 + req.MinConfirmations = 5 // needs chain at >= 105 + + result, err := client.ExecuteRead(context.Background(), req) + require.Error(t, err) + assert.Nil(t, result) + }) + + t.Run("executes once deep enough", func(t *testing.T) { + client := newReadTestClient(t, map[string]any{ + "eth_blockNumber": "0x69", // 105 + "eth_getBlockByNumber": fakeHeader(100), + "eth_getBalance": "0x1", + }, nil) + + req := evmReadRequest(t, uint8(evmQueryAccountBalance), 0, payload) + req.DestinationBlockHeight = 100 + req.MinConfirmations = 5 + + result, err := client.ExecuteRead(context.Background(), req) + require.NoError(t, err) + assert.Equal(t, uint64(100), result.ObservedBlockHeight) + }) +} diff --git a/universalClient/externalchains/evm/rpc_client.go b/universalClient/externalchains/evm/rpc_client.go index b8c83d04..433a8ef3 100644 --- a/universalClient/externalchains/evm/rpc_client.go +++ b/universalClient/externalchains/evm/rpc_client.go @@ -182,6 +182,45 @@ func (rc *RPCClient) GetBalance(ctx context.Context, address ethcommon.Address) return balance, err } +// GetBalanceAt fetches the native token balance for an address at a specific block. +func (rc *RPCClient) GetBalanceAt(ctx context.Context, address ethcommon.Address, blockNumber *big.Int) (*big.Int, error) { + var balance *big.Int + err := rc.executeWithFailover(ctx, "get_balance_at", func(client *ethclient.Client) error { + callCtx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + var innerErr error + balance, innerErr = client.BalanceAt(callCtx, address, blockNumber) + return innerErr + }) + return balance, err +} + +// GetStorageAt fetches a storage slot value for a contract at a specific block. +func (rc *RPCClient) GetStorageAt(ctx context.Context, address ethcommon.Address, slot ethcommon.Hash, blockNumber *big.Int) ([]byte, error) { + var value []byte + err := rc.executeWithFailover(ctx, "get_storage_at", func(client *ethclient.Client) error { + callCtx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + var innerErr error + value, innerErr = client.StorageAt(callCtx, address, slot, blockNumber) + return innerErr + }) + return value, err +} + +// GetHeaderByNumber fetches a block header by number. +func (rc *RPCClient) GetHeaderByNumber(ctx context.Context, blockNumber *big.Int) (*types.Header, error) { + var header *types.Header + err := rc.executeWithFailover(ctx, "get_header_by_number", func(client *ethclient.Client) error { + callCtx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + var innerErr error + header, innerErr = client.HeaderByNumber(callCtx, blockNumber) + return innerErr + }) + return header, err +} + // FilterLogs fetches logs matching the filter query func (rc *RPCClient) FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error) { var logs []types.Log diff --git a/universalClient/externalchains/svm/client.go b/universalClient/externalchains/svm/client.go index bdafd098..e0afd3a0 100644 --- a/universalClient/externalchains/svm/client.go +++ b/universalClient/externalchains/svm/client.go @@ -12,6 +12,7 @@ import ( "github.com/pushchain/push-chain-node/universalClient/db" "github.com/pushchain/push-chain-node/universalClient/externalchains/common" "github.com/pushchain/push-chain-node/universalClient/pushsigner" + "github.com/pushchain/push-chain-node/universalClient/store" uregistrytypes "github.com/pushchain/push-chain-node/x/uregistry/types" ) @@ -96,16 +97,14 @@ func NewClient( // Initialize components that don't require RPC client if pushSigner != nil { - inboundEnabled := config.Enabled != nil && config.Enabled.IsInboundEnabled - outboundEnabled := config.Enabled != nil && config.Enabled.IsOutboundEnabled - client.eventProcessor = common.NewEventProcessor( - pushSigner, - database, - chainIDStr, - inboundEnabled, - outboundEnabled, - log, - ) + ep := common.NewEventProcessor(database, chainIDStr, log) + if config.Enabled != nil && config.Enabled.IsInboundEnabled { + ep.RegisterHandler(store.EventTypeInbound, common.NewInboundObservationEventProcessor(pushSigner, database, log)) + } + if config.Enabled != nil && config.Enabled.IsOutboundEnabled { + ep.RegisterHandler(store.EventTypeOutbound, common.NewOutboundObservationEventProcessor(pushSigner, database, log)) + } + client.eventProcessor = ep } return client, nil @@ -209,6 +208,14 @@ func (c *Client) GetTxBuilder() (common.TxBuilder, error) { return c.txBuilder, nil } +// GetReadRequestHandler returns the read request handler for this chain +func (c *Client) GetReadRequestHandler() (common.ReadRequestHandler, error) { + if c.rpcClient == nil { + return nil, fmt.Errorf("read handler not available for chain %s (client not started)", c.chainIDStr) + } + return c, nil +} + // initializeComponents creates all components that require the RPC client func (c *Client) initializeComponents() error { // Create event listener if gateway is configured diff --git a/universalClient/externalchains/svm/event_parser.go b/universalClient/externalchains/svm/event_parser.go index 68f1dd4d..cc65ea4c 100644 --- a/universalClient/externalchains/svm/event_parser.go +++ b/universalClient/externalchains/svm/event_parser.go @@ -177,7 +177,7 @@ func parseOutboundObservationEvent(log string, signature string, slot uint64, lo } // Create OutboundEvent payload - payload := common.OutboundEvent{ + payload := common.OutboundObservation{ TxID: txID, UniversalTxID: universalTxID, GasFeeUsed: fmt.Sprintf("%d", gasUsed), @@ -250,7 +250,7 @@ func parseUniversalTxEvent(event *store.Event, decoded []byte, logIndex uint, ch } // decodeUniversalTxEvent decodes a TxWithFunds event -func decodeUniversalTxEvent(data []byte, logger zerolog.Logger) (*common.UniversalTx, error) { +func decodeUniversalTxEvent(data []byte, logger zerolog.Logger) (*common.InboundObservation, error) { if len(data) < 120 { logger.Warn(). Int("data_len", len(data)). @@ -258,7 +258,7 @@ func decodeUniversalTxEvent(data []byte, logger zerolog.Logger) (*common.Univers } offset := 8 - payload := &common.UniversalTx{} + payload := &common.InboundObservation{} // Parse sender (32 bytes) if len(data) < offset+32 { diff --git a/universalClient/externalchains/svm/event_parser_test.go b/universalClient/externalchains/svm/event_parser_test.go index 88ae4436..f7c6f060 100644 --- a/universalClient/externalchains/svm/event_parser_test.go +++ b/universalClient/externalchains/svm/event_parser_test.go @@ -307,7 +307,7 @@ func TestParseSendFundsEvent(t *testing.T) { assert.Equal(t, store.ConfirmationFast, event.ConfirmationType) // Unmarshal EventData - var utx common.UniversalTx + var utx common.InboundObservation require.NoError(t, json.Unmarshal(event.EventData, &utx)) assert.Equal(t, chainID, utx.SourceChain) @@ -344,7 +344,7 @@ func TestParseSendFundsEvent(t *testing.T) { data := buildSendFundsPayload(s, r, tok, 0, nil, rev, 0, nil, false) event := ParseEvent(wrapAsLog(data), sig, 1, 0, EventTypeSendFunds, chainID, logger) require.NotNil(t, event) - var utx common.UniversalTx + var utx common.InboundObservation require.NoError(t, json.Unmarshal(event.EventData, &utx)) assert.False(t, utx.FromCEA) }) @@ -355,7 +355,7 @@ func TestParseSendFundsEvent(t *testing.T) { data := buildSendFundsPayload(s, r, tok, 0, nil, rev, 0, nil, false) event := ParseEvent(wrapAsLog(data), sig, 1, 0, EventTypeSendFunds, chainID, logger) require.NotNil(t, event) - var utx common.UniversalTx + var utx common.InboundObservation require.NoError(t, json.Unmarshal(event.EventData, &utx)) assert.Empty(t, utx.RawPayload) assert.Empty(t, utx.VerificationData) @@ -368,7 +368,7 @@ func TestParseSendFundsEvent(t *testing.T) { data := buildSendFundsPayload(s, r, tok, maxU64, nil, rev, 0, nil, false) event := ParseEvent(wrapAsLog(data), sig, 1, 0, EventTypeSendFunds, chainID, logger) require.NotNil(t, event) - var utx common.UniversalTx + var utx common.InboundObservation require.NoError(t, json.Unmarshal(event.EventData, &utx)) assert.Equal(t, "18446744073709551615", utx.Amount) }) @@ -423,7 +423,7 @@ func TestParseOutboundObservationEvent(t *testing.T) { assert.Equal(t, store.StatusPending, event.Status) assert.Equal(t, store.ConfirmationStandard, event.ConfirmationType) - var outbound common.OutboundEvent + var outbound common.OutboundObservation require.NoError(t, json.Unmarshal(event.EventData, &outbound)) assert.Equal(t, "0x"+hex.EncodeToString(txID[:]), outbound.TxID) assert.Equal(t, "0x"+hex.EncodeToString(utxID[:]), outbound.UniversalTxID) @@ -439,7 +439,7 @@ func TestParseOutboundObservationEvent(t *testing.T) { event := ParseEvent(wrapAsLog(data), signature, 1, 0, EventTypeFinalizeUniversalTx, chainID, logger) require.NotNil(t, event) - var outbound common.OutboundEvent + var outbound common.OutboundObservation require.NoError(t, json.Unmarshal(event.EventData, &outbound)) assert.Equal(t, solana.PublicKeyFromBytes(token[:]).String(), outbound.Pc20WrapperAddress) }) @@ -450,7 +450,7 @@ func TestParseOutboundObservationEvent(t *testing.T) { event := ParseEvent(wrapAsLog(data), signature, 1, 0, EventTypeFinalizeUniversalTx, chainID, logger) require.NotNil(t, event) - var outbound common.OutboundEvent + var outbound common.OutboundObservation require.NoError(t, json.Unmarshal(event.EventData, &outbound)) assert.Empty(t, outbound.Pc20WrapperAddress) }) @@ -461,7 +461,7 @@ func TestParseOutboundObservationEvent(t *testing.T) { event := ParseEvent(wrapAsLog(data), signature, 1, 0, EventTypeRevertUniversalTx, chainID, logger) require.NotNil(t, event) - var outbound common.OutboundEvent + var outbound common.OutboundObservation require.NoError(t, json.Unmarshal(event.EventData, &outbound)) assert.Empty(t, outbound.Pc20WrapperAddress) assert.Equal(t, "7777", outbound.GasFeeUsed) @@ -473,7 +473,7 @@ func TestParseOutboundObservationEvent(t *testing.T) { event := ParseEvent(wrapAsLog(data), signature, 1, 0, EventTypeFundsRescued, chainID, logger) require.NotNil(t, event) - var outbound common.OutboundEvent + var outbound common.OutboundObservation require.NoError(t, json.Unmarshal(event.EventData, &outbound)) assert.Empty(t, outbound.Pc20WrapperAddress) assert.Equal(t, "3333", outbound.GasFeeUsed) @@ -514,7 +514,7 @@ func TestParseOutboundObservationEvent(t *testing.T) { event := ParseEvent(wrapAsLog(data), signature, 100, 0, EventTypeFinalizeUniversalTx, chainID, logger) require.NotNil(t, event) - var outbound common.OutboundEvent + var outbound common.OutboundObservation require.NoError(t, json.Unmarshal(event.EventData, &outbound)) assert.Contains(t, outbound.TxID, "0x1111") assert.Contains(t, outbound.UniversalTxID, "0x2222") @@ -536,7 +536,7 @@ func TestParseOutboundObservationEvent(t *testing.T) { event := ParseEvent(wrapAsLog(data), signature, 100, 0, EventTypeFinalizeUniversalTx, chainID, logger) require.NotNil(t, event) - var outbound common.OutboundEvent + var outbound common.OutboundObservation require.NoError(t, json.Unmarshal(event.EventData, &outbound)) assert.Equal(t, "0x"+hex.EncodeToString(txID[:]), outbound.TxID) assert.Equal(t, "0x"+hex.EncodeToString(utxID[:]), outbound.UniversalTxID) @@ -549,7 +549,7 @@ func TestParseOutboundObservationEvent(t *testing.T) { event := ParseEvent(wrapAsLog(data), signature, 100, 0, EventTypeFinalizeUniversalTx, chainID, logger) require.NotNil(t, event) - var outbound common.OutboundEvent + var outbound common.OutboundObservation require.NoError(t, json.Unmarshal(event.EventData, &outbound)) assert.Equal(t, "0", outbound.GasFeeUsed) }) @@ -560,7 +560,7 @@ func TestParseOutboundObservationEvent(t *testing.T) { event := ParseEvent(wrapAsLog(data), signature, 100, 0, EventTypeFinalizeUniversalTx, chainID, logger) require.NotNil(t, event) - var outbound common.OutboundEvent + var outbound common.OutboundObservation require.NoError(t, json.Unmarshal(event.EventData, &outbound)) assert.Equal(t, "18446744073709551615", outbound.GasFeeUsed) }) diff --git a/universalClient/externalchains/svm/read_envelope.go b/universalClient/externalchains/svm/read_envelope.go new file mode 100644 index 00000000..b32d172b --- /dev/null +++ b/universalClient/externalchains/svm/read_envelope.go @@ -0,0 +1,66 @@ +package svm + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" +) + +// solanaQueryType mirrors the SolanaQueryEnvelope enum from the read spec. +type solanaQueryType uint8 + +const ( + solanaQueryLamportBalance solanaQueryType = 0 + solanaQuerySPLTokenAccount solanaQueryType = 1 + solanaQueryRawAccountData solanaQueryType = 2 +) + +// solanaQueryEnvelope is the decoded abi.encode(SolanaQueryEnvelope) query — +// ABI-encoded because it is built by UniversalCallback.sol on Push EVM. +// The target account pubkey travels in ReadSpec.account.owner (32 bytes), not here. +type solanaQueryEnvelope struct { + QueryType solanaQueryType + MinSlot uint64 + Payload []byte // empty for all v1 query types +} + +var svmEnvelopeArgs = func() abi.Arguments { + tupleTy, err := abi.NewType("tuple", "", []abi.ArgumentMarshaling{ + {Name: "queryType", Type: "uint8"}, + {Name: "slotRef", Type: "tuple", Components: []abi.ArgumentMarshaling{ + {Name: "minSlot", Type: "uint64"}, + }}, + {Name: "payload", Type: "bytes"}, + }) + if err != nil { + panic(fmt.Sprintf("svm: invalid envelope abi type: %v", err)) + } + return abi.Arguments{{Name: "envelope", Type: tupleTy}} +}() + +type rawSvmEnvelope struct { + QueryType uint8 + SlotRef struct { + MinSlot uint64 + } + Payload []byte +} + +// decodeSolanaQueryEnvelope decodes ReadSpec.query for solana chains. +func decodeSolanaQueryEnvelope(query []byte) (*solanaQueryEnvelope, error) { + vals, err := svmEnvelopeArgs.Unpack(query) + if err != nil { + return nil, fmt.Errorf("failed to unpack SolanaQueryEnvelope: %w", err) + } + raw := *abi.ConvertType(vals[0], new(rawSvmEnvelope)).(*rawSvmEnvelope) + + env := &solanaQueryEnvelope{ + QueryType: solanaQueryType(raw.QueryType), + MinSlot: raw.SlotRef.MinSlot, + Payload: raw.Payload, + } + if env.QueryType > solanaQueryRawAccountData { + return nil, fmt.Errorf("unknown SolanaQueryType %d", env.QueryType) + } + return env, nil +} diff --git a/universalClient/externalchains/svm/read_envelope_test.go b/universalClient/externalchains/svm/read_envelope_test.go new file mode 100644 index 00000000..d5103053 --- /dev/null +++ b/universalClient/externalchains/svm/read_envelope_test.go @@ -0,0 +1,34 @@ +package svm + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestDecodeSolanaQueryEnvelope(t *testing.T) { + data, err := svmEnvelopeArgs.Pack(rawSvmEnvelope{ + QueryType: uint8(solanaQuerySPLTokenAccount), + SlotRef: struct { + MinSlot uint64 + }{42}, + Payload: nil, + }) + require.NoError(t, err) + + env, err := decodeSolanaQueryEnvelope(data) + require.NoError(t, err) + assert.Equal(t, solanaQuerySPLTokenAccount, env.QueryType) + assert.Equal(t, uint64(42), env.MinSlot) + assert.Empty(t, env.Payload) + + _, err = decodeSolanaQueryEnvelope([]byte{0x00}) + assert.Error(t, err) + + // unknown query type + bad, err := svmEnvelopeArgs.Pack(rawSvmEnvelope{QueryType: 9}) + require.NoError(t, err) + _, err = decodeSolanaQueryEnvelope(bad) + assert.Error(t, err) +} diff --git a/universalClient/externalchains/svm/read_executor.go b/universalClient/externalchains/svm/read_executor.go new file mode 100644 index 00000000..42e7c62e --- /dev/null +++ b/universalClient/externalchains/svm/read_executor.go @@ -0,0 +1,98 @@ +package svm + +import ( + "context" + "encoding/binary" + "fmt" + "math/big" + + "github.com/gagliardetto/solana-go" + + "github.com/pushchain/push-chain-node/universalClient/externalchains/common" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +// splTokenAmountOffset is the byte offset of the u64 amount in an SPL token account. +const splTokenAmountOffset = 64 + +// ExecuteRead implements common.ChainReader for Solana chains. +// +// Solana cannot query state at an exact past slot, so reads run at finalized +// commitment with minContextSlot as a staleness floor. ObservedBlockHeight (the +// context slot) may differ across validators; core's ballot key covers the +// result value only, never the observed slot. +func (c *Client) ExecuteRead(ctx context.Context, req *ucallbacktypes.ReadRequest) (*ucallbacktypes.ReadResult, error) { + env, err := decodeSolanaQueryEnvelope(req.Query) + if err != nil { + return common.NewReadErrorResult(err), nil + } + + if len(req.Owner) != solana.PublicKeyLength { + return common.NewReadErrorResult(fmt.Errorf("owner must be a 32-byte pubkey, got %d bytes", len(req.Owner))), nil + } + account := solana.PublicKeyFromBytes(req.Owner) + + minSlot := max(env.MinSlot, req.DestinationBlockHeight) + + switch env.QueryType { + case solanaQueryLamportBalance: + balance, slot, rpcErr := c.rpcClient.GetBalanceWithSlot(ctx, account) + if rpcErr != nil { + return nil, rpcErr + } + if slot < minSlot { + return nil, fmt.Errorf("observed slot %d below min slot %d", slot, minSlot) + } + resultData, encErr := common.EncodeUint256Result(new(big.Int).SetUint64(balance)) + if encErr != nil { + return common.NewReadErrorResult(encErr), nil + } + return &ucallbacktypes.ReadResult{ + Status: ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, + ResultData: resultData, + ObservedBlockHeight: slot, + }, nil + + case solanaQuerySPLTokenAccount: + data, owner, found, slot, rpcErr := c.rpcClient.GetAccountInfoWithSlot(ctx, account, minSlot) + if rpcErr != nil { + return nil, rpcErr + } + if !found { + return common.NewReadErrorResult(fmt.Errorf("token account %s not found", account)), nil + } + if !owner.Equals(solana.TokenProgramID) && !owner.Equals(solana.Token2022ProgramID) { + return common.NewReadErrorResult(fmt.Errorf("account %s is not owned by a token program", account)), nil + } + if len(data) < splTokenAmountOffset+8 { + return common.NewReadErrorResult(fmt.Errorf("token account data too short: %d bytes", len(data))), nil + } + amount := binary.LittleEndian.Uint64(data[splTokenAmountOffset : splTokenAmountOffset+8]) + resultData, encErr := common.EncodeUint256Result(new(big.Int).SetUint64(amount)) + if encErr != nil { + return common.NewReadErrorResult(encErr), nil + } + return &ucallbacktypes.ReadResult{ + Status: ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, + ResultData: resultData, + ObservedBlockHeight: slot, + }, nil + + case solanaQueryRawAccountData: + data, _, found, slot, rpcErr := c.rpcClient.GetAccountInfoWithSlot(ctx, account, minSlot) + if rpcErr != nil { + return nil, rpcErr + } + if !found { + return common.NewReadErrorResult(fmt.Errorf("account %s not found", account)), nil + } + return &ucallbacktypes.ReadResult{ + Status: ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, + ResultData: data, + ObservedBlockHeight: slot, + }, nil + + default: + return common.NewReadErrorResult(fmt.Errorf("unknown SolanaQueryType %d", env.QueryType)), nil + } +} diff --git a/universalClient/externalchains/svm/read_executor_test.go b/universalClient/externalchains/svm/read_executor_test.go new file mode 100644 index 00000000..b48271af --- /dev/null +++ b/universalClient/externalchains/svm/read_executor_test.go @@ -0,0 +1,210 @@ +package svm + +import ( + "context" + "encoding/base64" + "encoding/binary" + "encoding/json" + "math/big" + "net/http" + "net/http/httptest" + "testing" + + "github.com/gagliardetto/solana-go" + solrpc "github.com/gagliardetto/solana-go/rpc" + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +// accountInfoResult builds a getAccountInfo result with base64 data. +func accountInfoResult(slot uint64, owner solana.PublicKey, data []byte) map[string]any { + return map[string]any{ + "context": map[string]any{"slot": slot}, + "value": map[string]any{ + "data": []any{base64.StdEncoding.EncodeToString(data), "base64"}, + "executable": false, + "lamports": 1, + "owner": owner.String(), + "rentEpoch": 0, + }, + } +} + +// newReadTestClient spins up a JSON-RPC server answering from results keyed by +// method name, and returns a Client wired to it. +func newReadTestClient(t *testing.T, results map[string]any) *Client { + t.Helper() + + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var req struct { + ID json.RawMessage `json:"id"` + Method string `json:"method"` + } + require.NoError(t, json.NewDecoder(r.Body).Decode(&req)) + + resp := map[string]any{"jsonrpc": "2.0", "id": json.RawMessage(req.ID)} + if result, ok := results[req.Method]; ok { + resp["result"] = result + } else { + t.Errorf("unexpected RPC method %s", req.Method) + resp["error"] = map[string]any{"code": -32601, "message": "method not found"} + } + require.NoError(t, json.NewEncoder(w).Encode(resp)) + })) + t.Cleanup(srv.Close) + + return &Client{ + logger: zerolog.Nop(), + rpcClient: &RPCClient{clients: []*solrpc.Client{solrpc.New(srv.URL)}, logger: zerolog.Nop()}, + } +} + +func svmReadRequest(t *testing.T, queryType uint8, minSlot uint64, owner []byte) *ucallbacktypes.ReadRequest { + t.Helper() + query, err := svmEnvelopeArgs.Pack(rawSvmEnvelope{ + QueryType: queryType, + SlotRef: struct { + MinSlot uint64 + }{minSlot}, + }) + require.NoError(t, err) + return &ucallbacktypes.ReadRequest{ + RequestId: "0xreq1", + DestinationChain: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", + Owner: owner, + Query: query, + } +} + +func testAccount() solana.PublicKey { + return solana.MustPublicKeyFromBase58("So11111111111111111111111111111111111111112") +} + +func TestExecuteRead_LamportBalance(t *testing.T) { + account := testAccount() + + t.Run("success", func(t *testing.T) { + client := newReadTestClient(t, map[string]any{ + "getBalance": map[string]any{ + "context": map[string]any{"slot": 900}, + "value": 5_000_000, + }, + }) + + result, err := client.ExecuteRead(context.Background(), svmReadRequest(t, uint8(solanaQueryLamportBalance), 800, account.Bytes())) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, result.Status) + assert.Equal(t, big.NewInt(5_000_000), new(big.Int).SetBytes(result.ResultData)) + assert.Equal(t, uint64(900), result.ObservedBlockHeight) + }) + + t.Run("observed slot below min slot is transient", func(t *testing.T) { + client := newReadTestClient(t, map[string]any{ + "getBalance": map[string]any{ + "context": map[string]any{"slot": 700}, + "value": 5_000_000, + }, + }) + + result, err := client.ExecuteRead(context.Background(), svmReadRequest(t, uint8(solanaQueryLamportBalance), 800, account.Bytes())) + require.Error(t, err) + assert.Nil(t, result) + }) +} + +func TestExecuteRead_SPLTokenAccount(t *testing.T) { + account := testAccount() + + tokenAccountData := func(amount uint64) []byte { + data := make([]byte, 165) + binary.LittleEndian.PutUint64(data[splTokenAmountOffset:], amount) + return data + } + + t.Run("success", func(t *testing.T) { + client := newReadTestClient(t, map[string]any{ + "getAccountInfo": accountInfoResult(900, solana.TokenProgramID, tokenAccountData(777)), + }) + + result, err := client.ExecuteRead(context.Background(), svmReadRequest(t, uint8(solanaQuerySPLTokenAccount), 800, account.Bytes())) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, result.Status) + assert.Equal(t, big.NewInt(777), new(big.Int).SetBytes(result.ResultData)) + assert.Equal(t, uint64(900), result.ObservedBlockHeight) + }) + + t.Run("non token-program owner is a votable ERROR", func(t *testing.T) { + client := newReadTestClient(t, map[string]any{ + "getAccountInfo": accountInfoResult(900, solana.SystemProgramID, tokenAccountData(777)), + }) + + result, err := client.ExecuteRead(context.Background(), svmReadRequest(t, uint8(solanaQuerySPLTokenAccount), 0, account.Bytes())) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) + + t.Run("truncated account data is a votable ERROR", func(t *testing.T) { + client := newReadTestClient(t, map[string]any{ + "getAccountInfo": accountInfoResult(900, solana.TokenProgramID, make([]byte, 10)), + }) + + result, err := client.ExecuteRead(context.Background(), svmReadRequest(t, uint8(solanaQuerySPLTokenAccount), 0, account.Bytes())) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) + + t.Run("missing account is a votable ERROR", func(t *testing.T) { + client := newReadTestClient(t, map[string]any{ + "getAccountInfo": map[string]any{ + "context": map[string]any{"slot": 900}, + "value": nil, + }, + }) + + result, err := client.ExecuteRead(context.Background(), svmReadRequest(t, uint8(solanaQuerySPLTokenAccount), 0, account.Bytes())) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) +} + +func TestExecuteRead_RawAccountData(t *testing.T) { + account := testAccount() + raw := []byte{0x01, 0x02, 0x03} + + client := newReadTestClient(t, map[string]any{ + "getAccountInfo": accountInfoResult(900, solana.SystemProgramID, raw), + }) + + result, err := client.ExecuteRead(context.Background(), svmReadRequest(t, uint8(solanaQueryRawAccountData), 0, account.Bytes())) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, result.Status) + assert.Equal(t, raw, result.ResultData) + assert.Equal(t, uint64(900), result.ObservedBlockHeight) +} + +func TestExecuteRead_InvalidInputs(t *testing.T) { + account := testAccount() + + t.Run("invalid envelope is a votable ERROR", func(t *testing.T) { + client := newReadTestClient(t, nil) + + result, err := client.ExecuteRead(context.Background(), &ucallbacktypes.ReadRequest{ + RequestId: "0xreq1", + Owner: account.Bytes(), + Query: []byte{0x01}, + }) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) + + t.Run("owner not 32 bytes is a votable ERROR", func(t *testing.T) { + client := newReadTestClient(t, nil) + + result, err := client.ExecuteRead(context.Background(), svmReadRequest(t, uint8(solanaQueryLamportBalance), 0, []byte{0x01, 0x02})) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) +} diff --git a/universalClient/externalchains/svm/rpc_client.go b/universalClient/externalchains/svm/rpc_client.go index fb788b7a..ee1ac9a0 100644 --- a/universalClient/externalchains/svm/rpc_client.go +++ b/universalClient/externalchains/svm/rpc_client.go @@ -386,6 +386,53 @@ func (rc *RPCClient) GetAccountData(ctx context.Context, pubkey solana.PublicKey return accountData, err } +// GetBalanceWithSlot fetches the lamport balance for an account at finalized +// commitment, returning the context slot the value was observed at. +func (rc *RPCClient) GetBalanceWithSlot(ctx context.Context, pubkey solana.PublicKey) (uint64, uint64, error) { + var balance, slot uint64 + err := rc.executeWithFailover(ctx, "get_balance", func(client *rpc.Client) error { + resp, innerErr := client.GetBalance(ctx, pubkey, rpc.CommitmentFinalized) + if innerErr != nil { + return innerErr + } + balance = resp.Value + slot = resp.RPCContext.Context.Slot + return nil + }) + return balance, slot, err +} + +// GetAccountInfoWithSlot fetches account data at finalized commitment with an +// optional minimum context slot, returning the context slot it was observed at. +// found=false means the account does not exist (a valid, votable observation). +func (rc *RPCClient) GetAccountInfoWithSlot(ctx context.Context, pubkey solana.PublicKey, minContextSlot uint64) (data []byte, owner solana.PublicKey, found bool, slot uint64, err error) { + err = rc.executeWithFailover(ctx, "get_account_info", func(client *rpc.Client) error { + opts := &rpc.GetAccountInfoOpts{Commitment: rpc.CommitmentFinalized} + if minContextSlot > 0 { + opts.MinContextSlot = &minContextSlot + } + resp, innerErr := client.GetAccountInfoWithOpts(ctx, pubkey, opts) + if innerErr != nil { + if innerErr == rpc.ErrNotFound { + found = false + return nil + } + return innerErr + } + if resp.Value == nil { + found = false + slot = resp.RPCContext.Context.Slot + return nil + } + found = true + data = resp.Value.Data.GetBinary() + owner = resp.Value.Owner + slot = resp.RPCContext.Context.Slot + return nil + }) + return data, owner, found, slot, err +} + // Close closes all RPC connections func (rc *RPCClient) Close() { rc.mu.Lock() diff --git a/universalClient/externalchains/web2/read_envelope.go b/universalClient/externalchains/web2/read_envelope.go new file mode 100644 index 00000000..b56d1048 --- /dev/null +++ b/universalClient/externalchains/web2/read_envelope.go @@ -0,0 +1,140 @@ +package web2 + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" +) + +// web2Method mirrors the Web2QueryEnvelope method enum from the read spec. +type web2Method uint8 + +const ( + web2MethodGet web2Method = 0 + web2MethodPost web2Method = 1 +) + +// extractValueType mirrors the Web2Extract valueType enum. +type extractValueType uint8 + +const ( + valueTypeUint256 extractValueType = 0 + valueTypeInt256 extractValueType = 1 + valueTypeBool extractValueType = 2 + valueTypeString extractValueType = 3 + valueTypeBytes extractValueType = 4 +) + +// extractMode mirrors the Web2Extract mode enum. +type extractMode uint8 + +// modeIdentical is the only supported aggregation mode: quorum on identical +// result bytes. More modes (e.g. median) need core-side aggregation first. +const modeIdentical extractMode = 0 + +// web2Extract is one declared field to pull out of the JSON response. +type web2Extract struct { + Path string // JSONPath into the response, e.g. "$.data.price" + ValueType extractValueType + Mode extractMode + Decimals uint8 // numeric JSON scaled by 10^decimals before encoding +} + +// web2QueryEnvelope is the decoded abi.encode(Web2QueryEnvelope) query. +type web2QueryEnvelope struct { + Method web2Method + URL string + Headers []byte // canonical JSON object of header name -> value + Body []byte // POST only + TimeoutMs uint64 + Extract []web2Extract +} + +var web2EnvelopeArgs = mustReadArgs(abi.ArgumentMarshaling{Type: "tuple", Components: []abi.ArgumentMarshaling{ + {Name: "method", Type: "uint8"}, + {Name: "url", Type: "string"}, + {Name: "headers", Type: "bytes"}, + {Name: "body", Type: "bytes"}, + {Name: "timeoutMs", Type: "uint64"}, + {Name: "extract", Type: "tuple[]", Components: []abi.ArgumentMarshaling{ + {Name: "path", Type: "string"}, + {Name: "valueType", Type: "uint8"}, + {Name: "mode", Type: "uint8"}, + {Name: "decimals", Type: "uint8"}, + }}, +}}) + +func mustReadArgs(marshalings ...abi.ArgumentMarshaling) abi.Arguments { + args := make(abi.Arguments, 0, len(marshalings)) + for i, m := range marshalings { + if m.Name == "" { + m.Name = fmt.Sprintf("arg%d", i) + } + typ, err := abi.NewType(m.Type, "", m.Components) + if err != nil { + panic(fmt.Sprintf("web2: invalid abi type %q: %v", m.Type, err)) + } + args = append(args, abi.Argument{Name: m.Name, Type: typ}) + } + return args +} + +type rawWeb2Extract struct { + Path string + ValueType uint8 + Mode uint8 + Decimals uint8 +} + +type rawWeb2Envelope struct { + Method uint8 + Url string + Headers []byte + Body []byte + TimeoutMs uint64 + Extract []rawWeb2Extract +} + +// decodeWeb2QueryEnvelope decodes ReadSpec.query for web2 destinations. +func decodeWeb2QueryEnvelope(query []byte) (*web2QueryEnvelope, error) { + vals, err := web2EnvelopeArgs.Unpack(query) + if err != nil { + return nil, fmt.Errorf("failed to unpack Web2QueryEnvelope: %w", err) + } + raw := *abi.ConvertType(vals[0], new(rawWeb2Envelope)).(*rawWeb2Envelope) + + env := &web2QueryEnvelope{ + Method: web2Method(raw.Method), + URL: raw.Url, + Headers: raw.Headers, + Body: raw.Body, + TimeoutMs: raw.TimeoutMs, + } + for _, e := range raw.Extract { + env.Extract = append(env.Extract, web2Extract{ + Path: e.Path, + ValueType: extractValueType(e.ValueType), + Mode: extractMode(e.Mode), + Decimals: e.Decimals, + }) + } + + if env.Method > web2MethodPost { + return nil, fmt.Errorf("unknown web2 method %d", env.Method) + } + if len(env.Extract) == 0 { + return nil, fmt.Errorf("envelope has no extract entries") + } + if len(env.Extract) > maxExtractEntries { + return nil, fmt.Errorf("envelope has %d extract entries, max %d", len(env.Extract), maxExtractEntries) + } + for _, e := range env.Extract { + if e.ValueType > valueTypeBytes { + return nil, fmt.Errorf("unknown extract value type %d", e.ValueType) + } + if e.Mode != modeIdentical { + return nil, fmt.Errorf("unsupported extract mode %d, only IDENTICAL", e.Mode) + } + } + return env, nil +} diff --git a/universalClient/externalchains/web2/read_executor.go b/universalClient/externalchains/web2/read_executor.go new file mode 100644 index 00000000..b4acc0be --- /dev/null +++ b/universalClient/externalchains/web2/read_executor.go @@ -0,0 +1,422 @@ +// Package web2 executes web2 (HTTP) read requests: it fetches the declared +// endpoint, extracts the declared JSON fields, and canonically encodes them so +// read results are byte-identical across validators. +package web2 + +import ( + "bytes" + "context" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "io" + "math/big" + "net" + "net/http" + "strconv" + "strings" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/rs/zerolog" + + "github.com/pushchain/push-chain-node/universalClient/externalchains/common" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +const ( + // DestinationPrefix identifies web2 read destinations, e.g. "web2:https". + DestinationPrefix = "web2:" + + maxResponseBytes = 64 * 1024 + maxExtractEntries = 16 + defaultTimeout = 5 * time.Second + maxTimeout = 15 * time.Second + maxRedirects = 5 +) + +// errBlockedRequest marks a request rejected by the SSRF guard (private/internal +// address, disallowed redirect). It is deterministic: every honest validator +// rejects the same envelope identically, so it becomes a votable ERROR rather +// than a transient retry. +var errBlockedRequest = errors.New("request blocked by ssrf guard") + +// TODO(core): a web2 read makes every validator fetch an attacker-chosen URL, +// so the fee is the only thing pricing that outbound work. The fee must NEVER +// be fully refunded on failure or no-quorum: a full refund lets an attacker +// drive the whole validator set at any endpoint for only tx gas (griefing / +// reflected load). Charge for execution regardless of read outcome. + +// Executor implements common.ReadRequestHandler for web2 destinations. +type Executor struct { + httpClient *http.Client + logger zerolog.Logger + // allowInsecureURL disables the https-only rule (tests only) + allowInsecureURL bool +} + +// NewExecutor creates a web2 read executor. Its HTTP client dials through an +// SSRF guard that blocks private/internal addresses on the initial request and +// on every redirect hop, and only connects to the exact IP it vetted (so DNS +// rebinding cannot swap in an internal address between check and dial). +func NewExecutor(logger zerolog.Logger) *Executor { + e := &Executor{ + logger: logger.With().Str("component", "web2_read_executor").Logger(), + } + e.httpClient = &http.Client{ + Timeout: maxTimeout, + Transport: &http.Transport{DialContext: e.dialContext}, + CheckRedirect: e.checkRedirect, + } + return e +} + +// dialContext resolves the target host and refuses any non-public address, then +// dials the vetted IP directly. Tests set allowInsecureURL to reach httptest +// servers on loopback. +func (e *Executor) dialContext(ctx context.Context, network, addr string) (net.Conn, error) { + if e.allowInsecureURL { + return (&net.Dialer{}).DialContext(ctx, network, addr) + } + + host, port, err := net.SplitHostPort(addr) + if err != nil { + return nil, err + } + + ips, err := net.DefaultResolver.LookupIPAddr(ctx, host) + if err != nil { + return nil, err + } + if len(ips) == 0 { + return nil, fmt.Errorf("no addresses for %s", host) + } + for _, ip := range ips { + if isDisallowedIP(ip.IP) { + return nil, fmt.Errorf("%w: %s resolves to non-public address %s", errBlockedRequest, host, ip.IP) + } + } + + dialer := &net.Dialer{} + var lastErr error + for _, ip := range ips { + conn, err := dialer.DialContext(ctx, network, net.JoinHostPort(ip.IP.String(), port)) + if err != nil { + lastErr = err + continue + } + return conn, nil + } + return nil, lastErr +} + +// checkRedirect keeps redirects https-only and bounded. The dialer still vets +// every hop's address; this only rejects scheme downgrades and redirect loops. +func (e *Executor) checkRedirect(req *http.Request, via []*http.Request) error { + if len(via) >= maxRedirects { + return fmt.Errorf("%w: too many redirects", errBlockedRequest) + } + if !e.allowInsecureURL && req.URL.Scheme != "https" { + return fmt.Errorf("%w: redirect to non-https url", errBlockedRequest) + } + return nil +} + +// isDisallowedIP reports whether an IP is one the guard must never connect to: +// loopback, private (RFC1918 / ULA), link-local (incl. 169.254.169.254 cloud +// metadata), carrier-grade NAT, multicast, or the unspecified address. +func isDisallowedIP(ip net.IP) bool { + if ip.IsLoopback() || ip.IsPrivate() || ip.IsUnspecified() || + ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() || ip.IsMulticast() { + return true + } + // Carrier-grade NAT 100.64.0.0/10 (RFC 6598) is not covered by IsPrivate. + if v4 := ip.To4(); v4 != nil && v4[0] == 100 && v4[1]&0xc0 == 64 { + return true + } + return false +} + +// ExecuteRead fetches the endpoint declared in the envelope, extracts the +// declared fields, and abi-encodes them in extract order. Deterministic +// failures (bad envelope, non-JSON response, missing path, 4xx) are votable +// ERROR observations; transport failures and 5xx are transient errors. +func (e *Executor) ExecuteRead(ctx context.Context, req *ucallbacktypes.ReadRequest) (*ucallbacktypes.ReadResult, error) { + env, err := decodeWeb2QueryEnvelope(req.Query) + if err != nil { + return common.NewReadErrorResult(err), nil + } + + if err := e.validateEnvelope(env); err != nil { + return common.NewReadErrorResult(err), nil + } + + body, errResult, err := e.fetch(ctx, env) + if err != nil { + return nil, err // transient + } + if errResult != nil { + return errResult, nil + } + + resultData, err := extractAndEncode(body, env.Extract) + if err != nil { + return common.NewReadErrorResult(err), nil + } + + // web2 has no block height or hash; the ballot covers result data only + return &ucallbacktypes.ReadResult{ + Status: ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, + ResultData: resultData, + }, nil +} + +// validateEnvelope enforces the v1 request constraints. +func (e *Executor) validateEnvelope(env *web2QueryEnvelope) error { + if !e.allowInsecureURL && !strings.HasPrefix(env.URL, "https://") { + return fmt.Errorf("url must be https") + } + if env.Method == web2MethodGet && len(env.Body) > 0 { + return fmt.Errorf("GET request must not have a body") + } + return nil +} + +// fetch performs the HTTP request. Returns (body, nil, nil) on success, +// (nil, errorResult, nil) on deterministic failure, (nil, nil, err) on +// transient failure. +func (e *Executor) fetch(ctx context.Context, env *web2QueryEnvelope) ([]byte, *ucallbacktypes.ReadResult, error) { + timeout := defaultTimeout + if env.TimeoutMs > 0 { + timeout = min(time.Duration(env.TimeoutMs)*time.Millisecond, maxTimeout) + } + reqCtx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + method := http.MethodGet + var reqBody io.Reader + if env.Method == web2MethodPost { + method = http.MethodPost + reqBody = bytes.NewReader(env.Body) + } + + httpReq, err := http.NewRequestWithContext(reqCtx, method, env.URL, reqBody) + if err != nil { + return nil, common.NewReadErrorResult(fmt.Errorf("invalid request: %w", err)), nil + } + + if len(env.Headers) > 0 { + var headers map[string]string + if err := json.Unmarshal(env.Headers, &headers); err != nil { + return nil, common.NewReadErrorResult(fmt.Errorf("invalid headers encoding: %w", err)), nil + } + for name, value := range headers { + httpReq.Header.Set(name, value) + } + } + + resp, err := e.httpClient.Do(httpReq) + if err != nil { + // A guard rejection is the same for every validator: votable ERROR. + // Any other transport error may be transient. + if errors.Is(err, errBlockedRequest) { + return nil, common.NewReadErrorResult(fmt.Errorf("request blocked: %w", err)), nil + } + return nil, nil, fmt.Errorf("request failed: %w", err) // transient + } + defer func() { _ = resp.Body.Close() }() + + // 5xx, plus the transient 4xx codes 408 (Request Timeout) and 429 (Too Many + // Requests), mean "try again" — retry, never vote. Every other non-2xx is a + // deterministic answer from the endpoint and is votable. + if resp.StatusCode >= 500 || + resp.StatusCode == http.StatusRequestTimeout || + resp.StatusCode == http.StatusTooManyRequests { + return nil, nil, fmt.Errorf("endpoint returned status %d", resp.StatusCode) + } + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return nil, common.NewReadErrorResult(fmt.Errorf("endpoint returned status %d", resp.StatusCode)), nil + } + + body, err := io.ReadAll(io.LimitReader(resp.Body, maxResponseBytes+1)) + if err != nil { + return nil, nil, fmt.Errorf("failed to read response: %w", err) // transient + } + if len(body) > maxResponseBytes { + return nil, common.NewReadErrorResult(fmt.Errorf("response exceeds %d bytes", maxResponseBytes)), nil + } + + return body, nil, nil +} + +// extractAndEncode applies each extract spec to the JSON response and +// abi-encodes the values in extract order. +func extractAndEncode(body []byte, extracts []web2Extract) ([]byte, error) { + decoder := json.NewDecoder(bytes.NewReader(body)) + decoder.UseNumber() + var root any + if err := decoder.Decode(&root); err != nil { + return nil, fmt.Errorf("response is not valid JSON: %w", err) + } + + args := make(abi.Arguments, 0, len(extracts)) + values := make([]any, 0, len(extracts)) + for _, ex := range extracts { + raw, err := resolveJSONPath(root, ex.Path) + if err != nil { + return nil, err + } + + value, abiType, err := convertValue(raw, ex) + if err != nil { + return nil, fmt.Errorf("path %s: %w", ex.Path, err) + } + args = append(args, abi.Argument{Name: "v", Type: abiType}) + values = append(values, value) + } + + encoded, err := args.Pack(values...) + if err != nil { + return nil, fmt.Errorf("failed to encode result: %w", err) + } + return encoded, nil +} + +var ( + abiUint256, _ = abi.NewType("uint256", "", nil) + abiInt256, _ = abi.NewType("int256", "", nil) + abiBool, _ = abi.NewType("bool", "", nil) + abiString, _ = abi.NewType("string", "", nil) + abiBytes, _ = abi.NewType("bytes", "", nil) +) + +// convertValue converts a JSON value to the declared abi value. +func convertValue(raw any, ex web2Extract) (any, abi.Type, error) { + switch ex.ValueType { + case valueTypeUint256, valueTypeInt256: + num, err := scaledInteger(raw, ex.Decimals) + if err != nil { + return nil, abi.Type{}, err + } + if ex.ValueType == valueTypeUint256 { + if num.Sign() < 0 || num.BitLen() > 256 { + return nil, abi.Type{}, fmt.Errorf("value out of uint256 range") + } + return num, abiUint256, nil + } + if num.BitLen() > 255 { + return nil, abi.Type{}, fmt.Errorf("value out of int256 range") + } + return num, abiInt256, nil + + case valueTypeBool: + b, ok := raw.(bool) + if !ok { + return nil, abi.Type{}, fmt.Errorf("expected bool, got %T", raw) + } + return b, abiBool, nil + + case valueTypeString: + s, ok := raw.(string) + if !ok { + return nil, abi.Type{}, fmt.Errorf("expected string, got %T", raw) + } + return s, abiString, nil + + case valueTypeBytes: + s, ok := raw.(string) + if !ok || !strings.HasPrefix(s, "0x") { + return nil, abi.Type{}, fmt.Errorf("expected 0x-prefixed hex string") + } + decoded, err := hex.DecodeString(strings.TrimPrefix(s, "0x")) + if err != nil { + return nil, abi.Type{}, fmt.Errorf("invalid hex: %w", err) + } + return decoded, abiBytes, nil + + default: + return nil, abi.Type{}, fmt.Errorf("unknown value type %d", ex.ValueType) + } +} + +// scaledInteger parses a JSON number (or numeric string), scales it by +// 10^decimals, and truncates to an integer. big.Rat keeps float-formatted +// JSON exact (e.g. "3512.4471" with 8 decimals -> 351244710000). +func scaledInteger(raw any, decimals uint8) (*big.Int, error) { + var numStr string + switch v := raw.(type) { + case json.Number: + numStr = v.String() + case string: + numStr = v + default: + return nil, fmt.Errorf("expected number, got %T", raw) + } + + rat, ok := new(big.Rat).SetString(numStr) + if !ok { + return nil, fmt.Errorf("invalid number %q", numStr) + } + + scale := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(decimals)), nil) + rat.Mul(rat, new(big.Rat).SetInt(scale)) + + return new(big.Int).Quo(rat.Num(), rat.Denom()), nil +} + +// resolveJSONPath resolves a minimal JSONPath subset: "$" root, dot fields and +// array indexes, e.g. "$.data.items[0].price". +func resolveJSONPath(root any, path string) (any, error) { + if !strings.HasPrefix(path, "$") { + return nil, fmt.Errorf("path %s must start with $", path) + } + + current := root + rest := strings.TrimPrefix(path, "$") + for _, segment := range strings.Split(rest, ".") { + if segment == "" { + continue + } + + field := segment + var indexes []int + for strings.HasSuffix(field, "]") { + open := strings.LastIndex(field, "[") + if open < 0 { + return nil, fmt.Errorf("path %s has malformed index in %q", path, segment) + } + idx, err := strconv.Atoi(field[open+1 : len(field)-1]) + if err != nil || idx < 0 { + return nil, fmt.Errorf("path %s has invalid index in %q", path, segment) + } + indexes = append([]int{idx}, indexes...) + field = field[:open] + } + + if field != "" { + obj, ok := current.(map[string]any) + if !ok { + return nil, fmt.Errorf("path %s: %q is not an object", path, field) + } + value, ok := obj[field] + if !ok { + return nil, fmt.Errorf("path %s: field %q not found", path, field) + } + current = value + } + + for _, idx := range indexes { + arr, ok := current.([]any) + if !ok { + return nil, fmt.Errorf("path %s: indexing into non-array", path) + } + if idx >= len(arr) { + return nil, fmt.Errorf("path %s: index %d out of range", path, idx) + } + current = arr[idx] + } + } + + return current, nil +} diff --git a/universalClient/externalchains/web2/read_executor_test.go b/universalClient/externalchains/web2/read_executor_test.go new file mode 100644 index 00000000..f67f9031 --- /dev/null +++ b/universalClient/externalchains/web2/read_executor_test.go @@ -0,0 +1,423 @@ +package web2 + +import ( + "context" + "encoding/json" + "errors" + "math/big" + "net" + "net/http" + "net/http/httptest" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +func packEnvelope(t *testing.T, env rawWeb2Envelope) []byte { + t.Helper() + data, err := web2EnvelopeArgs.Pack(env) + require.NoError(t, err) + return data +} + +func extractSpec(path string, valueType extractValueType, decimals uint8) rawWeb2Extract { + return rawWeb2Extract{Path: path, ValueType: uint8(valueType), Mode: uint8(modeIdentical), Decimals: decimals} +} + +func newTestExecutor(t *testing.T, handler http.HandlerFunc) (*Executor, string) { + t.Helper() + srv := httptest.NewServer(handler) + t.Cleanup(srv.Close) + + e := NewExecutor(zerolog.Nop()) + e.allowInsecureURL = true // httptest serves plain http + return e, srv.URL +} + +func jsonHandler(t *testing.T, wantMethod string, response any) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, wantMethod, r.Method) + require.NoError(t, json.NewEncoder(w).Encode(response)) + } +} + +func web2Request(t *testing.T, env rawWeb2Envelope) *ucallbacktypes.ReadRequest { + t.Helper() + return &ucallbacktypes.ReadRequest{ + RequestId: "0xreq1", + DestinationChain: "web2:https", + Query: packEnvelope(t, env), + } +} + +func TestExecuteRead_GetIdenticalFields(t *testing.T) { + e, url := newTestExecutor(t, jsonHandler(t, http.MethodGet, map[string]any{ + "status": "FINAL", + "winner": "TeamA", + "score": map[string]any{"a": 3, "b": 1}, + })) + + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: url, + Extract: []rawWeb2Extract{ + extractSpec("$.status", valueTypeString, 0), + extractSpec("$.winner", valueTypeString, 0), + extractSpec("$.score.a", valueTypeUint256, 0), + }, + }) + + result, err := e.ExecuteRead(context.Background(), req) + require.NoError(t, err) + require.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, result.Status) + assert.Zero(t, result.ObservedBlockHeight) + + stringTy, _ := abi.NewType("string", "", nil) + uintTy, _ := abi.NewType("uint256", "", nil) + args := abi.Arguments{{Type: stringTy}, {Type: stringTy}, {Type: uintTy}} + vals, err := args.Unpack(result.ResultData) + require.NoError(t, err) + assert.Equal(t, "FINAL", vals[0]) + assert.Equal(t, "TeamA", vals[1]) + assert.Equal(t, big.NewInt(3), vals[2]) +} + +func TestExecuteRead_DecimalScaling(t *testing.T) { + e, url := newTestExecutor(t, jsonHandler(t, http.MethodGet, map[string]any{ + "price": 3512.4471, + })) + + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: url, + Extract: []rawWeb2Extract{extractSpec("$.price", valueTypeUint256, 8)}, + }) + + result, err := e.ExecuteRead(context.Background(), req) + require.NoError(t, err) + require.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, result.Status) + + assert.Equal(t, big.NewInt(351244710000), new(big.Int).SetBytes(result.ResultData)) +} + +func TestExecuteRead_PostBody(t *testing.T) { + e, url := newTestExecutor(t, func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodPost, r.Method) + assert.Equal(t, "application/json", r.Header.Get("Content-Type")) + var body map[string]string + require.NoError(t, json.NewDecoder(r.Body).Decode(&body)) + assert.Equal(t, "{ token { decimals } }", body["query"]) + require.NoError(t, json.NewEncoder(w).Encode(map[string]any{ + "data": map[string]any{"token": map[string]any{"decimals": 18}}, + })) + }) + + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodPost), + Url: url, + Headers: []byte(`{"content-type":"application/json"}`), + Body: []byte(`{"query":"{ token { decimals } }"}`), + Extract: []rawWeb2Extract{extractSpec("$.data.token.decimals", valueTypeUint256, 0)}, + }) + + result, err := e.ExecuteRead(context.Background(), req) + require.NoError(t, err) + require.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, result.Status) + assert.Equal(t, big.NewInt(18), new(big.Int).SetBytes(result.ResultData)) +} + +func TestExecuteRead_ArrayIndexPath(t *testing.T) { + e, url := newTestExecutor(t, jsonHandler(t, http.MethodGet, map[string]any{ + "items": []any{map[string]any{"ok": true}, map[string]any{"ok": false}}, + })) + + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: url, + Extract: []rawWeb2Extract{extractSpec("$.items[1].ok", valueTypeBool, 0)}, + }) + + result, err := e.ExecuteRead(context.Background(), req) + require.NoError(t, err) + require.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, result.Status) + + boolTy, _ := abi.NewType("bool", "", nil) + vals, err := abi.Arguments{{Type: boolTy}}.Unpack(result.ResultData) + require.NoError(t, err) + assert.Equal(t, false, vals[0]) +} + +func TestExecuteRead_VotableErrors(t *testing.T) { + t.Run("invalid envelope", func(t *testing.T) { + e := NewExecutor(zerolog.Nop()) + result, err := e.ExecuteRead(context.Background(), &ucallbacktypes.ReadRequest{Query: []byte{0x01}}) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) + + t.Run("non-https url", func(t *testing.T) { + e := NewExecutor(zerolog.Nop()) + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: "http://insecure.example.com", + Extract: []rawWeb2Extract{extractSpec("$.x", valueTypeString, 0)}, + }) + result, err := e.ExecuteRead(context.Background(), req) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) + + t.Run("non-identical mode not supported", func(t *testing.T) { + e := NewExecutor(zerolog.Nop()) + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: "https://api.example.com", + Extract: []rawWeb2Extract{ + {Path: "$.price", ValueType: uint8(valueTypeUint256), Mode: 1, Decimals: 8}, + }, + }) + result, err := e.ExecuteRead(context.Background(), req) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) + + t.Run("GET with body", func(t *testing.T) { + e := NewExecutor(zerolog.Nop()) + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: "https://api.example.com", + Body: []byte("nope"), + Extract: []rawWeb2Extract{extractSpec("$.x", valueTypeString, 0)}, + }) + result, err := e.ExecuteRead(context.Background(), req) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) + + t.Run("missing path", func(t *testing.T) { + e, url := newTestExecutor(t, jsonHandler(t, http.MethodGet, map[string]any{"a": 1})) + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: url, + Extract: []rawWeb2Extract{extractSpec("$.missing", valueTypeUint256, 0)}, + }) + result, err := e.ExecuteRead(context.Background(), req) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) + + t.Run("type mismatch", func(t *testing.T) { + e, url := newTestExecutor(t, jsonHandler(t, http.MethodGet, map[string]any{"a": "text"})) + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: url, + Extract: []rawWeb2Extract{extractSpec("$.a", valueTypeBool, 0)}, + }) + result, err := e.ExecuteRead(context.Background(), req) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) + + t.Run("non-JSON response", func(t *testing.T) { + e, url := newTestExecutor(t, func(w http.ResponseWriter, r *http.Request) { + _, _ = w.Write([]byte("not json")) + }) + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: url, + Extract: []rawWeb2Extract{extractSpec("$.a", valueTypeString, 0)}, + }) + result, err := e.ExecuteRead(context.Background(), req) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) + + t.Run("404 status", func(t *testing.T) { + e, url := newTestExecutor(t, func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotFound) + }) + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: url, + Extract: []rawWeb2Extract{extractSpec("$.a", valueTypeString, 0)}, + }) + result, err := e.ExecuteRead(context.Background(), req) + require.NoError(t, err) + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) +} + +func TestExecuteRead_TransientErrors(t *testing.T) { + t.Run("500 status", func(t *testing.T) { + e, url := newTestExecutor(t, func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + }) + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: url, + Extract: []rawWeb2Extract{extractSpec("$.a", valueTypeString, 0)}, + }) + result, err := e.ExecuteRead(context.Background(), req) + require.Error(t, err) + assert.Nil(t, result) + }) + + t.Run("unreachable endpoint", func(t *testing.T) { + e := NewExecutor(zerolog.Nop()) + e.allowInsecureURL = true + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: "http://127.0.0.1:1", + TimeoutMs: 500, + Extract: []rawWeb2Extract{extractSpec("$.a", valueTypeString, 0)}, + }) + result, err := e.ExecuteRead(context.Background(), req) + require.Error(t, err) + assert.Nil(t, result) + }) + + // 408 and 429 are retryable 4xx codes: retry, never vote. + for _, tc := range []struct { + name string + code int + }{ + {"408 request timeout", http.StatusRequestTimeout}, + {"429 too many requests", http.StatusTooManyRequests}, + } { + t.Run(tc.name, func(t *testing.T) { + e, url := newTestExecutor(t, func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(tc.code) + }) + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: url, + Extract: []rawWeb2Extract{extractSpec("$.a", valueTypeString, 0)}, + }) + result, err := e.ExecuteRead(context.Background(), req) + require.Error(t, err) + assert.Nil(t, result) + }) + } +} + +func TestExecuteRead_SSRFGuard(t *testing.T) { + // guard is active only when allowInsecureURL is false + blocked := []string{ + "https://127.0.0.1/x", + "https://[::1]/x", + "https://169.254.169.254/latest/meta-data/", + "https://10.0.0.1/x", + "https://192.168.1.1/x", + "https://172.16.0.1/x", + "https://100.64.0.1/x", + "https://0.0.0.0/x", + } + for _, target := range blocked { + t.Run(target, func(t *testing.T) { + e := NewExecutor(zerolog.Nop()) + req := web2Request(t, rawWeb2Envelope{ + Method: uint8(web2MethodGet), + Url: target, + TimeoutMs: 1000, + Extract: []rawWeb2Extract{extractSpec("$.x", valueTypeString, 0)}, + }) + result, err := e.ExecuteRead(context.Background(), req) + require.NoError(t, err) // deterministic, not transient + assert.Equal(t, ucallbacktypes.ReadStatus_READ_STATUS_ERROR, result.Status) + }) + } +} + +func TestCheckRedirect(t *testing.T) { + e := NewExecutor(zerolog.Nop()) + + mustReq := func(rawURL string) *http.Request { + r, err := http.NewRequest(http.MethodGet, rawURL, nil) + require.NoError(t, err) + return r + } + + // https redirect within the hop budget is allowed + assert.NoError(t, e.checkRedirect(mustReq("https://example.com/next"), make([]*http.Request, 1))) + + // scheme downgrade to http is blocked + err := e.checkRedirect(mustReq("http://example.com/next"), make([]*http.Request, 1)) + require.Error(t, err) + assert.True(t, errors.Is(err, errBlockedRequest)) + + // too many redirects is blocked + err = e.checkRedirect(mustReq("https://example.com/next"), make([]*http.Request, maxRedirects)) + require.Error(t, err) + assert.True(t, errors.Is(err, errBlockedRequest)) +} + +func TestIsDisallowedIP(t *testing.T) { + disallowed := []string{ + "127.0.0.1", "::1", "10.1.2.3", "172.16.5.5", "192.168.0.1", + "169.254.169.254", "100.64.0.1", "0.0.0.0", "fe80::1", "fc00::1", "224.0.0.1", + // IPv4-mapped IPv6 must not slip past the v4-range checks + "::ffff:127.0.0.1", "::ffff:169.254.169.254", "::ffff:10.0.0.1", + } + for _, s := range disallowed { + assert.True(t, isDisallowedIP(net.ParseIP(s)), "%s should be blocked", s) + } + + allowed := []string{"8.8.8.8", "1.1.1.1", "93.184.216.34", "2606:2800:220:1::1", "100.63.255.255", "100.128.0.1"} + for _, s := range allowed { + assert.False(t, isDisallowedIP(net.ParseIP(s)), "%s should be allowed", s) + } +} + +func TestScaledInteger(t *testing.T) { + cases := []struct { + in string + decimals uint8 + want string + }{ + {"3512.4471", 8, "351244710000"}, + {"100", 0, "100"}, + {"0.5", 2, "50"}, + {"1.999", 0, "1"}, // truncates + {"-2.5", 1, "-25"}, + } + for _, tc := range cases { + got, err := scaledInteger(json.Number(tc.in), tc.decimals) + require.NoError(t, err, tc.in) + assert.Equal(t, tc.want, got.String(), tc.in) + } + + _, err := scaledInteger(json.Number("not-a-number"), 0) + assert.Error(t, err) + _, err = scaledInteger(true, 0) + assert.Error(t, err) +} + +func TestDecodeWeb2QueryEnvelope_Invalid(t *testing.T) { + t.Run("garbage bytes", func(t *testing.T) { + _, err := decodeWeb2QueryEnvelope([]byte{0x01, 0x02}) + assert.Error(t, err) + }) + + t.Run("no extract entries", func(t *testing.T) { + data, err := web2EnvelopeArgs.Pack(rawWeb2Envelope{Method: 0, Url: "https://x"}) + require.NoError(t, err) + _, err = decodeWeb2QueryEnvelope(data) + assert.Error(t, err) + }) + + t.Run("unknown method", func(t *testing.T) { + data, err := web2EnvelopeArgs.Pack(rawWeb2Envelope{ + Method: 9, + Url: "https://x", + Extract: []rawWeb2Extract{{Path: "$.a"}}, + }) + require.NoError(t, err) + _, err = decodeWeb2QueryEnvelope(data) + assert.Error(t, err) + }) +} diff --git a/universalClient/pushcore/pushCore.go b/universalClient/pushcore/pushCore.go index 647b548e..600c4836 100644 --- a/universalClient/pushcore/pushCore.go +++ b/universalClient/pushcore/pushCore.go @@ -16,6 +16,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/authz" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" uexecutortypes "github.com/pushchain/push-chain-node/x/uexecutor/types" uregistrytypes "github.com/pushchain/push-chain-node/x/uregistry/types" utsstypes "github.com/pushchain/push-chain-node/x/utss/types" @@ -34,6 +35,7 @@ type Client struct { uvalidatorClients []uvalidatortypes.QueryClient // Universal validator query clients utssClients []utsstypes.QueryClient // TSS query clients uexecutorClients []uexecutortypes.QueryClient // Executor query clients (for gas price queries) + ucallbackClients []ucallbacktypes.QueryClient // Callback query clients (for pending read requests) cmtClients []cmtservice.ServiceClient // CometBFT service clients txClients []tx.ServiceClient // Transaction service clients authzClients []authz.QueryClient // AuthZ query clients @@ -65,6 +67,7 @@ func New(urls []string, logger zerolog.Logger) (*Client, error) { c.uvalidatorClients = append(c.uvalidatorClients, uvalidatortypes.NewQueryClient(conn)) c.utssClients = append(c.utssClients, utsstypes.NewQueryClient(conn)) c.uexecutorClients = append(c.uexecutorClients, uexecutortypes.NewQueryClient(conn)) + c.ucallbackClients = append(c.ucallbackClients, ucallbacktypes.NewQueryClient(conn)) c.cmtClients = append(c.cmtClients, cmtservice.NewServiceClient(conn)) c.txClients = append(c.txClients, tx.NewServiceClient(conn)) c.authzClients = append(c.authzClients, authz.NewQueryClient(conn)) @@ -93,6 +96,7 @@ func (c *Client) Close() error { c.uvalidatorClients = nil c.utssClients = nil c.uexecutorClients = nil + c.ucallbackClients = nil c.cmtClients = nil c.txClients = nil c.authzClients = nil @@ -367,6 +371,31 @@ func (c *Client) GetAllPendingOutbounds(ctx context.Context) ([]*uexecutortypes. return resp.Entries, resp.Outbounds, nil } +// GetAllPendingReadRequests retrieves up to the first 1000 pending external read +// requests from Push Chain. The query already withholds requests past their expiry +// height, so validators never take on work that can no longer be fulfilled in time. +func (c *Client) GetAllPendingReadRequests(ctx context.Context) ([]*ucallbacktypes.ReadRequest, error) { + return retryWithRoundRobin( + len(c.ucallbackClients), + &c.rr, + func(idx int) ([]*ucallbacktypes.ReadRequest, error) { + resp, err := c.ucallbackClients[idx].AllPendingReadRequests(ctx, &ucallbacktypes.QueryAllPendingReadRequestsRequest{ + Pagination: &query.PageRequest{Limit: 1000}, + }) + if err != nil { + return nil, err + } + requests := make([]*ucallbacktypes.ReadRequest, 0, len(resp.Reads)) + for i := range resp.Reads { + requests = append(requests, resp.Reads[i].Request) + } + return requests, nil + }, + "GetAllPendingReadRequests", + c.logger, + ) +} + // createGRPCConnection creates a gRPC connection with appropriate transport security. // It automatically detects whether to use TLS based on the URL scheme // and adds default port 9090 if no port is specified. diff --git a/universalClient/pushcore/pushCore_test.go b/universalClient/pushcore/pushCore_test.go index 323372b4..964540f7 100644 --- a/universalClient/pushcore/pushCore_test.go +++ b/universalClient/pushcore/pushCore_test.go @@ -10,6 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/authz" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" uexecutortypes "github.com/pushchain/push-chain-node/x/uexecutor/types" uregistrytypes "github.com/pushchain/push-chain-node/x/uregistry/types" utsstypes "github.com/pushchain/push-chain-node/x/utss/types" @@ -823,6 +824,73 @@ func TestClient_GetAllPendingOutbounds(t *testing.T) { }) } +func TestClient_GetAllPendingReadRequests(t *testing.T) { + logger := zerolog.Nop() + ctx := context.Background() + + t.Run("no endpoints configured", func(t *testing.T) { + client := &Client{ + logger: logger, + ucallbackClients: []ucallbacktypes.QueryClient{}, + } + + reqs, err := client.GetAllPendingReadRequests(ctx) + require.Error(t, err) + assert.Contains(t, err.Error(), "no endpoints configured") + assert.Nil(t, reqs) + }) + + t.Run("successful query maps UniversalRead.Request", func(t *testing.T) { + mockClient := &mockUCallbackQueryClient{ + allPendingReadsResp: &ucallbacktypes.QueryAllPendingReadRequestsResponse{ + Reads: []ucallbacktypes.UniversalRead{ + {Id: "0xr1", Request: &ucallbacktypes.ReadRequest{RequestId: "0xr1", DestinationChain: "eip155:1"}}, + {Id: "0xr2", Request: &ucallbacktypes.ReadRequest{RequestId: "0xr2", DestinationChain: "web2:https"}}, + }, + }, + } + + client := &Client{ + logger: logger, + ucallbackClients: []ucallbacktypes.QueryClient{mockClient}, + } + + reqs, err := client.GetAllPendingReadRequests(ctx) + require.NoError(t, err) + require.Len(t, reqs, 2) + assert.Equal(t, "0xr1", reqs[0].RequestId) + assert.Equal(t, "web2:https", reqs[1].DestinationChain) + }) + + t.Run("empty response", func(t *testing.T) { + mockClient := &mockUCallbackQueryClient{ + allPendingReadsResp: &ucallbacktypes.QueryAllPendingReadRequestsResponse{}, + } + + client := &Client{ + logger: logger, + ucallbackClients: []ucallbacktypes.QueryClient{mockClient}, + } + + reqs, err := client.GetAllPendingReadRequests(ctx) + require.NoError(t, err) + assert.Empty(t, reqs) + }) + + t.Run("all endpoints fail", func(t *testing.T) { + client := &Client{ + logger: logger, + ucallbackClients: []ucallbacktypes.QueryClient{ + &mockUCallbackQueryClient{err: assert.AnError}, + }, + } + + reqs, err := client.GetAllPendingReadRequests(ctx) + require.Error(t, err) + assert.Nil(t, reqs) + }) +} + func TestClient_GetGasPrice_NilResponse(t *testing.T) { logger := zerolog.Nop() mockClient := &mockUExecutorQueryClient{ @@ -965,10 +1033,10 @@ func (m *mockUValidatorQueryClient) UniversalValidator(ctx context.Context, req type mockUTSSQueryClient struct { utsstypes.QueryClient - currentKeyResp *utsstypes.QueryCurrentKeyResponse - pendingTssEventsResp *utsstypes.QueryAllPendingTssEventsResponse - pendingFundMigrationsResp *utsstypes.QueryPendingFundMigrationsResponse - err error + currentKeyResp *utsstypes.QueryCurrentKeyResponse + pendingTssEventsResp *utsstypes.QueryAllPendingTssEventsResponse + pendingFundMigrationsResp *utsstypes.QueryPendingFundMigrationsResponse + err error } func (m *mockUTSSQueryClient) CurrentKey(ctx context.Context, req *utsstypes.QueryCurrentKeyRequest, opts ...grpc.CallOption) (*utsstypes.QueryCurrentKeyResponse, error) { @@ -1084,3 +1152,16 @@ func (m *mockAuthAccountQueryClient) Account(ctx context.Context, req *authtypes } return m.accountResp, nil } + +type mockUCallbackQueryClient struct { + ucallbacktypes.QueryClient + allPendingReadsResp *ucallbacktypes.QueryAllPendingReadRequestsResponse + err error +} + +func (m *mockUCallbackQueryClient) AllPendingReadRequests(ctx context.Context, req *ucallbacktypes.QueryAllPendingReadRequestsRequest, opts ...grpc.CallOption) (*ucallbacktypes.QueryAllPendingReadRequestsResponse, error) { + if m.err != nil { + return nil, m.err + } + return m.allPendingReadsResp, nil +} diff --git a/universalClient/pushsigner/grant_verifier.go b/universalClient/pushsigner/grant_verifier.go index a4e92b4d..ef507f39 100644 --- a/universalClient/pushsigner/grant_verifier.go +++ b/universalClient/pushsigner/grant_verifier.go @@ -26,6 +26,7 @@ var requiredMsgGrants = []string{ "/uexecutor.v1.MsgVoteOutbound", "/utss.v1.MsgVoteTssKeyProcess", "/utss.v1.MsgVoteFundMigration", + "/ucallback.v1.MsgVoteReadResult", } // GrantInfo represents information about a single AuthZ grant. diff --git a/universalClient/pushsigner/grant_verifier_test.go b/universalClient/pushsigner/grant_verifier_test.go index 2c0ec770..ecb67089 100644 --- a/universalClient/pushsigner/grant_verifier_test.go +++ b/universalClient/pushsigner/grant_verifier_test.go @@ -28,6 +28,7 @@ func TestVerifyGrants(t *testing.T) { {Granter: granter, MessageType: "/uexecutor.v1.MsgVoteOutbound", Expiration: &futureTime}, {Granter: granter, MessageType: "/utss.v1.MsgVoteTssKeyProcess", Expiration: &futureTime}, {Granter: granter, MessageType: "/utss.v1.MsgVoteFundMigration", Expiration: &futureTime}, + {Granter: granter, MessageType: "/ucallback.v1.MsgVoteReadResult", Expiration: &futureTime}, } msgs, err := verifyGrants(grants, granter) @@ -47,6 +48,7 @@ func TestVerifyGrants(t *testing.T) { {Granter: granter, MessageType: "/uexecutor.v1.MsgVoteOutbound", Expiration: nil}, {Granter: granter, MessageType: "/utss.v1.MsgVoteTssKeyProcess", Expiration: nil}, {Granter: granter, MessageType: "/utss.v1.MsgVoteFundMigration", Expiration: nil}, + {Granter: granter, MessageType: "/ucallback.v1.MsgVoteReadResult", Expiration: nil}, } msgs, err := verifyGrants(grants, granter) @@ -115,6 +117,7 @@ func TestVerifyGrants(t *testing.T) { {Granter: granter, MessageType: "/uexecutor.v1.MsgVoteOutbound", Expiration: &futureTime}, {Granter: granter, MessageType: "/utss.v1.MsgVoteTssKeyProcess", Expiration: &futureTime}, {Granter: granter, MessageType: "/utss.v1.MsgVoteFundMigration", Expiration: &futureTime}, + {Granter: granter, MessageType: "/ucallback.v1.MsgVoteReadResult", Expiration: &futureTime}, } msgs, err := verifyGrants(grants, granter) @@ -129,6 +132,7 @@ func TestVerifyGrants(t *testing.T) { {Granter: granter, MessageType: "/uexecutor.v1.MsgVoteOutbound", Expiration: &futureTime}, {Granter: granter, MessageType: "/utss.v1.MsgVoteTssKeyProcess", Expiration: &futureTime}, {Granter: granter, MessageType: "/utss.v1.MsgVoteFundMigration", Expiration: &futureTime}, + {Granter: granter, MessageType: "/ucallback.v1.MsgVoteReadResult", Expiration: &futureTime}, {Granter: granter, MessageType: "/some.other.v1.MsgNotRequired", Expiration: &futureTime}, // Extra grant } diff --git a/universalClient/pushsigner/pushsigner.go b/universalClient/pushsigner/pushsigner.go index 8e8dcbfe..af14c153 100644 --- a/universalClient/pushsigner/pushsigner.go +++ b/universalClient/pushsigner/pushsigner.go @@ -24,6 +24,7 @@ import ( "github.com/pushchain/push-chain-node/universalClient/config" "github.com/pushchain/push-chain-node/universalClient/pushcore" "github.com/pushchain/push-chain-node/universalClient/pushsigner/keys" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" uexecutortypes "github.com/pushchain/push-chain-node/x/uexecutor/types" ) @@ -132,6 +133,11 @@ func (s *Signer) VoteFundMigration(ctx context.Context, migrationID uint64, txHa return voteFundMigration(ctx, s, s.log, s.granter, migrationID, txHash, success) } +// VoteReadResult votes on an external read observation. +func (s *Signer) VoteReadResult(ctx context.Context, requestID string, result *ucallbacktypes.ReadResult) (string, error) { + return voteReadResult(ctx, s, s.log, s.granter, requestID, result) +} + // signAndBroadcastAuthZTx signs and broadcasts an AuthZ transaction func (s *Signer) signAndBroadcastAuthZTx( ctx context.Context, @@ -411,6 +417,7 @@ func createClientContext(kr cosmoskeyring.Keyring, chainID string) client.Contex stakingtypes.RegisterInterfaces(interfaceRegistry) govtypes.RegisterInterfaces(interfaceRegistry) uexecutortypes.RegisterInterfaces(interfaceRegistry) + ucallbacktypes.RegisterInterfaces(interfaceRegistry) cdc := codec.NewProtoCodec(interfaceRegistry) txConfig := authtx.NewTxConfig(cdc, []signing.SignMode{signing.SignMode_SIGN_MODE_DIRECT}) diff --git a/universalClient/pushsigner/pushsigner_test.go b/universalClient/pushsigner/pushsigner_test.go index 331a407e..d80dbea9 100644 --- a/universalClient/pushsigner/pushsigner_test.go +++ b/universalClient/pushsigner/pushsigner_test.go @@ -18,6 +18,7 @@ import ( "github.com/pushchain/push-chain-node/universalClient/config" "github.com/pushchain/push-chain-node/universalClient/pushcore" "github.com/pushchain/push-chain-node/universalClient/pushsigner/keys" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" uexecutortypes "github.com/pushchain/push-chain-node/x/uexecutor/types" ) @@ -625,6 +626,36 @@ func TestVoteFundMigrationFailure(t *testing.T) { assert.Equal(t, "VOTE_OK", txHash) } +func TestVoteReadResult(t *testing.T) { + result := &ucallbacktypes.ReadResult{ + Status: ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, + ResultData: []byte{0xaa}, + ObservedBlockHeight: 100, + } + + t.Run("successful vote", func(t *testing.T) { + signer := createTestSigner(t, successMock(t)) + txHash, err := signer.VoteReadResult(context.Background(), "0xreq1", result) + require.NoError(t, err) + assert.Equal(t, "VOTE_OK", txHash) + }) + + t.Run("error observation votes too", func(t *testing.T) { + signer := createTestSigner(t, successMock(t)) + errResult := &ucallbacktypes.ReadResult{Status: ucallbacktypes.ReadStatus_READ_STATUS_ERROR} + txHash, err := signer.VoteReadResult(context.Background(), "0xreq2", errResult) + require.NoError(t, err) + assert.Equal(t, "VOTE_OK", txHash) + }) + + t.Run("broadcast failure", func(t *testing.T) { + signer := createTestSigner(t, failMock(t)) + _, err := signer.VoteReadResult(context.Background(), "0xreq1", result) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to broadcast vote") + }) +} + func TestVoteOnChainRejection(t *testing.T) { mock := &mockChainClient{ getAccountFn: func(ctx context.Context, address string) (*authtypes.QueryAccountResponse, error) { diff --git a/universalClient/pushsigner/vote.go b/universalClient/pushsigner/vote.go index 3312f463..593375c5 100644 --- a/universalClient/pushsigner/vote.go +++ b/universalClient/pushsigner/vote.go @@ -8,6 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/rs/zerolog" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" uexecutortypes "github.com/pushchain/push-chain-node/x/uexecutor/types" utsstypes "github.com/pushchain/push-chain-node/x/utss/types" ) @@ -105,6 +106,24 @@ func waitForTxConfirmation(ctx context.Context, client chainClient, txHash strin } } +// voteReadResult votes on an external read observation +func voteReadResult( + ctx context.Context, + signer *Signer, + log zerolog.Logger, + granter string, + requestID string, + result *ucallbacktypes.ReadResult, +) (string, error) { + msg := &ucallbacktypes.MsgVoteReadResult{ + Signer: granter, + RequestId: requestID, + Result: result, + } + memo := fmt.Sprintf("Vote read result: %s", requestID) + return vote(ctx, signer, log, msg, memo) +} + // voteInbound votes on an inbound transaction func voteInbound( ctx context.Context, diff --git a/universalClient/pushwatcher/client.go b/universalClient/pushwatcher/client.go index 351b38b9..875400f8 100644 --- a/universalClient/pushwatcher/client.go +++ b/universalClient/pushwatcher/client.go @@ -9,28 +9,36 @@ import ( "github.com/pushchain/push-chain-node/universalClient/config" "github.com/pushchain/push-chain-node/universalClient/db" "github.com/pushchain/push-chain-node/universalClient/externalchains/common" + "github.com/pushchain/push-chain-node/universalClient/externalchains/web2" "github.com/pushchain/push-chain-node/universalClient/pushcore" + "github.com/pushchain/push-chain-node/universalClient/pushsigner" + "github.com/pushchain/push-chain-node/universalClient/store" "github.com/rs/zerolog" ) // Client implements the ChainClient interface for Push chain type Client struct { - logger zerolog.Logger - pushCore *pushcore.Client - database *db.DB - eventListener *EventListener - eventCleaner *common.EventCleaner - ctx context.Context - cancel context.CancelFunc + logger zerolog.Logger + pushCore *pushcore.Client + database *db.DB + eventListener *EventListener + eventCleaner *common.EventCleaner + eventProcessor *EventProcessor + ctx context.Context + cancel context.CancelFunc } -// NewClient creates a new Push chain client +// NewClient creates a new Push chain client. +// pushSigner and chainResolver may be nil; the READ_REQUEST handler is only +// registered when both are present. func NewClient( database *db.DB, chainConfig *config.ChainSpecificConfig, pushCore *pushcore.Client, chainID string, logger zerolog.Logger, + pushSigner *pushsigner.Signer, + chainResolver ChainResolver, ) (*Client, error) { // Normalize nil config so downstream uses don't need nil guards. if chainConfig == nil { @@ -64,6 +72,22 @@ func NewClient( eventCleaner: eventCleaner, } + eventProcessor, err := NewEventProcessor(database, eventListener.cfg.PollInterval, logger) + if err != nil { + return nil, fmt.Errorf("failed to create event processor: %w", err) + } + + // READ_REQUEST events are executed on their destination chains (via + // chainResolver) and the results voted back. + if pushSigner != nil && chainResolver != nil { + readEventProcessor, err := NewReadEventProcessor(pushSigner, chainResolver, web2.NewExecutor(logger), database, logger) + if err != nil { + return nil, fmt.Errorf("failed to create read event processor: %w", err) + } + eventProcessor.RegisterHandler(store.EventTypeReadRequest, readEventProcessor) + } + client.eventProcessor = eventProcessor + return client, nil } @@ -85,6 +109,13 @@ func (c *Client) Start(ctx context.Context) error { } } + // Start event processor + if c.eventProcessor != nil { + if err := c.eventProcessor.Start(c.ctx); err != nil { + return fmt.Errorf("failed to start event processor: %w", err) + } + } + c.logger.Info().Msg("Push chain client started successfully") return nil } @@ -110,6 +141,13 @@ func (c *Client) Stop() error { c.eventCleaner.Stop() } + // Stop event processor + if c.eventProcessor != nil { + if err := c.eventProcessor.Stop(); err != nil { + c.logger.Error().Err(err).Str("subsystem", "event_processor").Msg("subsystem failed to stop") + } + } + c.logger.Info().Msg("Push chain client stopped") return nil } diff --git a/universalClient/pushwatcher/client_test.go b/universalClient/pushwatcher/client_test.go index 26877bea..8df232c4 100644 --- a/universalClient/pushwatcher/client_test.go +++ b/universalClient/pushwatcher/client_test.go @@ -34,7 +34,7 @@ func TestNewClient(t *testing.T) { pc := newTestPushCoreClient() t.Run("success with nil config", func(t *testing.T) { - client, err := NewClient(database, nil, pc, "push-chain", logger) + client, err := NewClient(database, nil, pc, "push-chain", logger, nil, nil) require.NoError(t, err) require.NotNil(t, client) assert.NotNil(t, client.eventListener) @@ -48,27 +48,27 @@ func TestNewClient(t *testing.T) { CleanupIntervalSeconds: &cleanup, RetentionPeriodSeconds: &retention, } - client, err := NewClient(database, cfg, pc, "push-chain", logger) + client, err := NewClient(database, cfg, pc, "push-chain", logger, nil, nil) require.NoError(t, err) require.NotNil(t, client) assert.NotNil(t, client.eventCleaner) }) t.Run("nil pushcore fails", func(t *testing.T) { - _, err := NewClient(database, nil, nil, "push-chain", logger) + _, err := NewClient(database, nil, nil, "push-chain", logger, nil, nil) require.Error(t, err) assert.Contains(t, err.Error(), "push client is nil") }) t.Run("nil database fails", func(t *testing.T) { - _, err := NewClient(nil, nil, pc, "push-chain", logger) + _, err := NewClient(nil, nil, pc, "push-chain", logger, nil, nil) require.Error(t, err) assert.Contains(t, err.Error(), "database is nil") }) } func TestClient_StartStop(t *testing.T) { - client, err := NewClient(newTestDB(t), nil, newTestPushCoreClient(), "push-chain", zerolog.Nop()) + client, err := NewClient(newTestDB(t), nil, newTestPushCoreClient(), "push-chain", zerolog.Nop(), nil, nil) require.NoError(t, err) ctx := context.Background() @@ -96,7 +96,7 @@ func TestClient_StopBeforeStart(t *testing.T) { // Stop on a freshly created client (never started) should not panic. // The cancel func is nil, eventListener.Stop() returns ErrNotRunning but // the client logs and swallows that error, returning nil. - client, err := NewClient(newTestDB(t), nil, newTestPushCoreClient(), "push-chain", zerolog.Nop()) + client, err := NewClient(newTestDB(t), nil, newTestPushCoreClient(), "push-chain", zerolog.Nop(), nil, nil) require.NoError(t, err) // Should not panic or return error @@ -104,7 +104,7 @@ func TestClient_StopBeforeStart(t *testing.T) { } func TestClient_DoubleStop(t *testing.T) { - client, err := NewClient(newTestDB(t), nil, newTestPushCoreClient(), "push-chain", zerolog.Nop()) + client, err := NewClient(newTestDB(t), nil, newTestPushCoreClient(), "push-chain", zerolog.Nop(), nil, nil) require.NoError(t, err) ctx := context.Background() @@ -122,7 +122,7 @@ func TestClient_StartStopWithEventCleaner(t *testing.T) { CleanupIntervalSeconds: &cleanup, RetentionPeriodSeconds: &retention, } - client, err := NewClient(newTestDB(t), cfg, newTestPushCoreClient(), "push-chain", zerolog.Nop()) + client, err := NewClient(newTestDB(t), cfg, newTestPushCoreClient(), "push-chain", zerolog.Nop(), nil, nil) require.NoError(t, err) require.NotNil(t, client.eventCleaner) @@ -140,7 +140,7 @@ func TestClient_StartStopWithEventCleaner(t *testing.T) { func TestClient_StartStopLifecycleMultiple(t *testing.T) { // Verify the client can be started and stopped multiple times (restart). - client, err := NewClient(newTestDB(t), nil, newTestPushCoreClient(), "push-chain", zerolog.Nop()) + client, err := NewClient(newTestDB(t), nil, newTestPushCoreClient(), "push-chain", zerolog.Nop(), nil, nil) require.NoError(t, err) ctx := context.Background() @@ -183,7 +183,7 @@ func TestNewClient_CleanerAlwaysWired(t *testing.T) { } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { - client, err := NewClient(database, tc.cfg, pc, "push-chain", logger) + client, err := NewClient(database, tc.cfg, pc, "push-chain", logger, nil, nil) require.NoError(t, err) require.NotNil(t, client.eventCleaner, "cleaner must always be wired up") }) @@ -199,7 +199,7 @@ func TestNewClient_NegativePollInterval(t *testing.T) { cfg := &config.ChainSpecificConfig{ EventPollingIntervalSeconds: &poll, } - client, err := NewClient(database, cfg, pc, "push-chain", logger) + client, err := NewClient(database, cfg, pc, "push-chain", logger, nil, nil) require.NoError(t, err) // Negative poll interval should fall back to default assert.Equal(t, DefaultPollInterval, client.eventListener.cfg.PollInterval) diff --git a/universalClient/pushwatcher/event_listener.go b/universalClient/pushwatcher/event_listener.go index 7193f444..511c7ee2 100644 --- a/universalClient/pushwatcher/event_listener.go +++ b/universalClient/pushwatcher/event_listener.go @@ -28,8 +28,9 @@ type Config struct { PollInterval time.Duration } -// EventListener polls Push chain for active TSS events and pending outbounds -// via gRPC, converts them to store.Events, and inserts them into the local DB. +// EventListener polls Push chain for active TSS events, pending outbounds and +// pending read requests via gRPC, converts them to store.Events, and inserts +// them into the local DB. type EventListener struct { pushCore *pushcore.Client chainStore *common.ChainStore @@ -134,17 +135,19 @@ func (el *EventListener) run(ctx context.Context) { } } -// poll fetches pending TSS, outbound & fund migration events, stores them, and updates latest block height. +// poll fetches pending TSS, outbound, fund migration & read request events, stores them, and updates latest block height. func (el *EventListener) poll(ctx context.Context) { tssCount := el.pollTssEvents(ctx) outboundCount := el.pollOutboundEvents(ctx) migrationCount := el.pollFundMigrationEvents(ctx) + readCount := el.pollReadRequestEvents(ctx) - if total := tssCount + outboundCount + migrationCount; total > 0 { + if total := tssCount + outboundCount + migrationCount + readCount; total > 0 { el.logger.Info(). Int("tss_events", tssCount). Int("outbound_events", outboundCount). Int("migration_events", migrationCount). + Int("read_request_events", readCount). Msg("stored new events") } @@ -235,6 +238,29 @@ func (el *EventListener) pollFundMigrationEvents(ctx context.Context) int { return newCount } +// pollReadRequestEvents fetches pending external read requests and inserts +// them into the DB. Returns new event count. +func (el *EventListener) pollReadRequestEvents(ctx context.Context) int { + requests, err := el.pushCore.GetAllPendingReadRequests(ctx) + if err != nil { + el.logger.Error().Err(err).Msg("failed to fetch pending read requests") + return 0 + } + + var newCount int + for _, req := range requests { + event, err := convertReadRequestEvent(req) + if err != nil { + el.logger.Warn().Err(err).Str("request_id", req.RequestId).Msg("failed to convert read request") + continue + } + + newCount += el.storeEvent(event) + } + + return newCount +} + // storeEvent inserts an event into the DB if it doesn't already exist. // Returns 1 if stored, 0 if duplicate or error. func (el *EventListener) storeEvent(event *store.Event) int { diff --git a/universalClient/pushwatcher/event_parser.go b/universalClient/pushwatcher/event_parser.go index a2644d7d..476f7090 100644 --- a/universalClient/pushwatcher/event_parser.go +++ b/universalClient/pushwatcher/event_parser.go @@ -7,6 +7,7 @@ import ( "fmt" "github.com/pushchain/push-chain-node/universalClient/store" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" uexecutortypes "github.com/pushchain/push-chain-node/x/uexecutor/types" utsstypes "github.com/pushchain/push-chain-node/x/utss/types" ) @@ -94,6 +95,28 @@ func convertFundMigrationEvent(migration *utsstypes.FundMigration) (*store.Event }, nil } +// convertReadRequestEvent converts a pending external read request to a store.Event. +func convertReadRequestEvent(req *ucallbacktypes.ReadRequest) (*store.Event, error) { + if req == nil || req.RequestId == "" { + return nil, fmt.Errorf("read request is nil or missing request id") + } + + eventData, err := json.Marshal(req) + if err != nil { + return nil, fmt.Errorf("failed to marshal read request event data: %w", err) + } + + return &store.Event{ + EventID: req.RequestId, // globally unique on-chain nonce; no hashing needed + BlockHeight: req.CreatedAtHeight, + ExpiryBlockHeight: req.ExpiryBlockHeight, + Type: store.EventTypeReadRequest, + ConfirmationType: store.ConfirmationInstant, + Status: store.StatusConfirmed, + EventData: eventData, + }, nil +} + // convertOutboundToEvent converts a PendingOutboundEntry + OutboundTx to a store.Event. func convertOutboundToEvent(entry *uexecutortypes.PendingOutboundEntry, outbound *uexecutortypes.OutboundTx) (*store.Event, error) { if entry == nil || outbound == nil { diff --git a/universalClient/pushwatcher/event_parser_test.go b/universalClient/pushwatcher/event_parser_test.go index cf8a98dc..fae4c123 100644 --- a/universalClient/pushwatcher/event_parser_test.go +++ b/universalClient/pushwatcher/event_parser_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" "github.com/pushchain/push-chain-node/universalClient/store" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" uexecutortypes "github.com/pushchain/push-chain-node/x/uexecutor/types" utsstypes "github.com/pushchain/push-chain-node/x/utss/types" ) @@ -397,6 +398,56 @@ func TestConvertFundMigrationEvent(t *testing.T) { }) } +func TestConvertReadRequestEvent(t *testing.T) { + t.Run("nil request returns error", func(t *testing.T) { + result, err := convertReadRequestEvent(nil) + require.Error(t, err) + assert.Nil(t, result) + assert.Contains(t, err.Error(), "read request is nil or missing request id") + }) + + t.Run("empty request id returns error", func(t *testing.T) { + result, err := convertReadRequestEvent(&ucallbacktypes.ReadRequest{RequestId: ""}) + require.Error(t, err) + assert.Nil(t, result) + assert.Contains(t, err.Error(), "read request is nil or missing request id") + }) + + t.Run("valid request converts correctly", func(t *testing.T) { + req := &ucallbacktypes.ReadRequest{ + RequestId: "0x00000000000000000000000000000000000000000000000000000000000000a1", + DestinationChain: "eip155:11155111", + Owner: []byte{0x01, 0x02}, + Query: []byte{0xde, 0xad}, + MinConfirmations: 3, + DestinationBlockHeight: 500, + ExpiryBlockHeight: 900, + CreatedAtHeight: 420, + } + + result, err := convertReadRequestEvent(req) + require.NoError(t, err) + require.NotNil(t, result) + + // EventID is the on-chain requestId verbatim (no hashing) + assert.Equal(t, req.RequestId, result.EventID) + assert.Equal(t, store.EventTypeReadRequest, result.Type) + assert.Equal(t, store.StatusConfirmed, result.Status) + assert.Equal(t, store.ConfirmationInstant, result.ConfirmationType) + assert.Equal(t, uint64(420), result.BlockHeight, "block height is the request's created-at height") + assert.Equal(t, uint64(900), result.ExpiryBlockHeight, "expiry height must be stamped for the processor's expiry check") + + // EventData round-trips back to the request + var decoded ucallbacktypes.ReadRequest + require.NoError(t, json.Unmarshal(result.EventData, &decoded)) + assert.Equal(t, req.RequestId, decoded.RequestId) + assert.Equal(t, req.DestinationChain, decoded.DestinationChain) + assert.Equal(t, req.Query, decoded.Query) + assert.Equal(t, req.MinConfirmations, decoded.MinConfirmations) + assert.Equal(t, req.DestinationBlockHeight, decoded.DestinationBlockHeight) + }) +} + func TestHashEventID(t *testing.T) { t.Run("deterministic output", func(t *testing.T) { id1 := hashEventID("keygen", "123") diff --git a/universalClient/pushwatcher/event_processor.go b/universalClient/pushwatcher/event_processor.go new file mode 100644 index 00000000..f848ae76 --- /dev/null +++ b/universalClient/pushwatcher/event_processor.go @@ -0,0 +1,151 @@ +package pushwatcher + +import ( + "context" + "sync" + "time" + + "github.com/pushchain/push-chain-node/universalClient/db" + "github.com/pushchain/push-chain-node/universalClient/externalchains/common" + "github.com/pushchain/push-chain-node/universalClient/store" + "github.com/rs/zerolog" +) + +const eventProcessBatchSize = 1000 + +// EventHandler processes one CONFIRMED push chain event of a registered type. +// Handlers own the event's status transitions; a returned error is logged and +// the event is retried next tick. +type EventHandler interface { + HandleEvent(ctx context.Context, event *store.Event) error +} + +// EventProcessor drains CONFIRMED events from the push chain DB and dispatches +// them to the handler registered for their type. Event types without a handler +// are ignored (e.g. TSS events, which are consumed by the TSS subsystem). +type EventProcessor struct { + chainStore *common.ChainStore + handlers map[string]EventHandler + cfg Config + logger zerolog.Logger + + mu sync.Mutex + running bool + cancel context.CancelFunc + wg sync.WaitGroup +} + +// NewEventProcessor creates a new push event processor. Register handlers +// before Start. +func NewEventProcessor( + database *db.DB, + pollInterval time.Duration, + logger zerolog.Logger, +) (*EventProcessor, error) { + if database == nil { + return nil, ErrNilDatabase + } + + if pollInterval <= 0 { + pollInterval = DefaultPollInterval + } + + return &EventProcessor{ + chainStore: common.NewChainStore(database), + handlers: make(map[string]EventHandler), + cfg: Config{PollInterval: pollInterval}, + logger: logger.With().Str("component", "push_event_processor").Logger(), + }, nil +} + +// RegisterHandler registers a handler for an event type. Must be called before Start. +func (p *EventProcessor) RegisterHandler(eventType string, handler EventHandler) { + p.handlers[eventType] = handler +} + +// Start begins processing events. +func (p *EventProcessor) Start(ctx context.Context) error { + p.mu.Lock() + defer p.mu.Unlock() + + if p.running { + return ErrAlreadyRunning + } + + childCtx, cancel := context.WithCancel(ctx) + p.cancel = cancel + p.running = true + + p.logger.Debug(). + Dur("poll_interval", p.cfg.PollInterval). + Msg("starting push event processor") + + p.wg.Add(1) + go p.run(childCtx) + + return nil +} + +// Stop gracefully stops the processor. +func (p *EventProcessor) Stop() error { + p.mu.Lock() + defer p.mu.Unlock() + + if !p.running { + return ErrNotRunning + } + + p.cancel() + p.wg.Wait() + p.running = false + + return nil +} + +func (p *EventProcessor) run(ctx context.Context) { + defer p.wg.Done() + + p.processConfirmedEvents(ctx) + + ticker := time.NewTicker(p.cfg.PollInterval) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + p.processConfirmedEvents(ctx) + } + } +} + +// processConfirmedEvents dispatches CONFIRMED events to their registered handlers. +func (p *EventProcessor) processConfirmedEvents(ctx context.Context) { + events, err := p.chainStore.GetConfirmedEvents(eventProcessBatchSize) + if err != nil { + p.logger.Error().Err(err).Msg("failed to query confirmed events") + return + } + + for _, event := range events { + handler, ok := p.handlers[event.Type] + if !ok { + continue + } + + select { + case <-ctx.Done(): + return + default: + } + + if err := handler.HandleEvent(ctx, &event); err != nil { + p.logger.Error(). + Err(err). + Str("event_id", event.EventID). + Str("type", event.Type). + Msg("failed to process event") + } + } +} diff --git a/universalClient/pushwatcher/event_processor_test.go b/universalClient/pushwatcher/event_processor_test.go new file mode 100644 index 00000000..92e60bcd --- /dev/null +++ b/universalClient/pushwatcher/event_processor_test.go @@ -0,0 +1,90 @@ +package pushwatcher + +import ( + "context" + "fmt" + "testing" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/pushchain/push-chain-node/universalClient/externalchains/common" + "github.com/pushchain/push-chain-node/universalClient/store" +) + +type fakeEventHandler struct { + handled []string + err error +} + +func (f *fakeEventHandler) HandleEvent(ctx context.Context, event *store.Event) error { + f.handled = append(f.handled, event.EventID) + return f.err +} + +func seedEvent(t *testing.T, cs *common.ChainStore, eventID, eventType string) { + t.Helper() + stored, err := cs.InsertEventIfNotExists(&store.Event{ + EventID: eventID, + Type: eventType, + ConfirmationType: store.ConfirmationInstant, + Status: store.StatusConfirmed, + EventData: []byte("{}"), + }) + require.NoError(t, err) + require.True(t, stored) +} + +func TestEventProcessor_DispatchesByType(t *testing.T) { + database := newTestDB(t) + p, err := NewEventProcessor(database, 0, zerolog.Nop()) + require.NoError(t, err) + cs := common.NewChainStore(database) + + readHandler := &fakeEventHandler{} + p.RegisterHandler(store.EventTypeReadRequest, readHandler) + + seedEvent(t, cs, "read-1", store.EventTypeReadRequest) + seedEvent(t, cs, "tss-1", store.EventTypeKeygen) // no handler registered + + p.processConfirmedEvents(context.Background()) + + assert.Equal(t, []string{"read-1"}, readHandler.handled) +} + +func TestEventProcessor_HandlerErrorKeepsProcessing(t *testing.T) { + database := newTestDB(t) + p, err := NewEventProcessor(database, 0, zerolog.Nop()) + require.NoError(t, err) + cs := common.NewChainStore(database) + + failing := &fakeEventHandler{err: fmt.Errorf("boom")} + p.RegisterHandler(store.EventTypeReadRequest, failing) + + seedEvent(t, cs, "read-1", store.EventTypeReadRequest) + seedEvent(t, cs, "read-2", store.EventTypeReadRequest) + + p.processConfirmedEvents(context.Background()) + + // both attempted despite errors, both still CONFIRMED for retry + assert.Len(t, failing.handled, 2) + events, err := cs.GetConfirmedEvents(10) + require.NoError(t, err) + assert.Len(t, events, 2) +} + +func TestEventProcessor_NilDatabase(t *testing.T) { + _, err := NewEventProcessor(nil, 0, zerolog.Nop()) + assert.ErrorIs(t, err, ErrNilDatabase) +} + +func TestEventProcessor_StartStop(t *testing.T) { + p, err := NewEventProcessor(newTestDB(t), 0, zerolog.Nop()) + require.NoError(t, err) + + require.NoError(t, p.Start(context.Background())) + assert.Equal(t, ErrAlreadyRunning, p.Start(context.Background())) + require.NoError(t, p.Stop()) + assert.Equal(t, ErrNotRunning, p.Stop()) +} diff --git a/universalClient/pushwatcher/read_event_processor.go b/universalClient/pushwatcher/read_event_processor.go new file mode 100644 index 00000000..c6f4e63b --- /dev/null +++ b/universalClient/pushwatcher/read_event_processor.go @@ -0,0 +1,150 @@ +package pushwatcher + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + "github.com/pushchain/push-chain-node/universalClient/db" + "github.com/pushchain/push-chain-node/universalClient/externalchains/common" + "github.com/pushchain/push-chain-node/universalClient/externalchains/web2" + "github.com/pushchain/push-chain-node/universalClient/store" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" + "github.com/rs/zerolog" +) + +// ChainResolver resolves a CAIP-2 chain ID to its chain client. +// Satisfied by externalchains.Chains. +type ChainResolver interface { + GetClient(chainID string) (common.ChainClient, error) +} + +// readVoter submits a read observation vote to Push Chain. +// Satisfied by *pushsigner.Signer. +type readVoter interface { + VoteReadResult(ctx context.Context, requestID string, result *ucallbacktypes.ReadResult) (string, error) +} + +// ReadEventProcessor handles READ_REQUEST events: it executes each request on +// its destination chain via the resolved read handler and votes the result. +// Transient failures (destination not served, RPC errors, vote failure) keep +// the event CONFIRMED for retry; corrupt events flip to REVERTED. Expiry is +// core's job: expired requests leave the pending query. +type ReadEventProcessor struct { + voter readVoter + resolver ChainResolver + web2Handler common.ReadRequestHandler + chainStore *common.ChainStore + logger zerolog.Logger +} + +// NewReadEventProcessor creates the handler for READ_REQUEST events. +// web2Handler serves web2 destinations; nil means web2 reads are not served. +func NewReadEventProcessor( + voter readVoter, + resolver ChainResolver, + web2Handler common.ReadRequestHandler, + database *db.DB, + logger zerolog.Logger, +) (*ReadEventProcessor, error) { + if database == nil { + return nil, ErrNilDatabase + } + + return &ReadEventProcessor{ + voter: voter, + resolver: resolver, + web2Handler: web2Handler, + chainStore: common.NewChainStore(database), + logger: logger.With().Str("component", "push_read_event_processor").Logger(), + }, nil +} + +// HandleEvent implements EventHandler for READ_REQUEST events. +func (p *ReadEventProcessor) HandleEvent(ctx context.Context, event *store.Event) error { + if p.isExpired(event) { + p.logger.Info().Str("event_id", event.EventID).Msg("read request expired; marking reverted") + p.markReverted(event.EventID) + return nil + } + + var req ucallbacktypes.ReadRequest + if err := json.Unmarshal(event.EventData, &req); err != nil { + p.markReverted(event.EventID) + return err + } + + log := p.logger.With().Str("request_id", req.RequestId).Logger() + + handler, err := p.resolveHandler(req.DestinationChain) + if err != nil { + // destination not served by this validator yet; retry next tick + log.Debug().Err(err).Str("destination_chain", req.DestinationChain).Msg("destination not served") + return nil + } + + result, err := handler.ExecuteRead(ctx, &req) + if err != nil { + log.Debug().Err(err).Str("destination_chain", req.DestinationChain).Msg("read execution failed; will retry") + return nil + } + + voteTxHash, err := p.voter.VoteReadResult(ctx, req.RequestId, result) + if err != nil { + log.Warn().Err(err).Msg("failed to vote read result; will retry") + return nil + } + + rowsAffected, err := p.chainStore.UpdateStatusAndVoteTxHash(event.EventID, store.StatusConfirmed, store.StatusCompleted, voteTxHash) + if err != nil { + return err + } + if rowsAffected == 0 { + return nil + } + + log.Info(). + Str("vote_tx_hash", voteTxHash). + Int32("status", int32(result.Status)). + Uint64("observed_height", result.ObservedBlockHeight). + Msg("read request voted") + + return nil +} + +// resolveHandler returns the read handler for a destination: the web2 executor +// for web2 destinations, otherwise the destination chain client's handler. +func (p *ReadEventProcessor) resolveHandler(destination string) (common.ReadRequestHandler, error) { + if strings.HasPrefix(destination, web2.DestinationPrefix) { + if p.web2Handler == nil { + return nil, fmt.Errorf("web2 reads not served") + } + return p.web2Handler, nil + } + + destClient, err := p.resolver.GetClient(destination) + if err != nil { + return nil, err + } + return destClient.GetReadRequestHandler() +} + +// isExpired reports whether the request's expiry Push chain height has been +// reached, using the chain height persisted by the event listener. +func (p *ReadEventProcessor) isExpired(event *store.Event) bool { + if event.ExpiryBlockHeight == 0 { + return false + } + pushHeight, err := p.chainStore.GetChainHeight() + if err != nil { + return false + } + return pushHeight >= event.ExpiryBlockHeight +} + +func (p *ReadEventProcessor) markReverted(eventID string) { + if _, err := p.chainStore.UpdateEventStatus(eventID, store.StatusConfirmed, store.StatusReverted); err != nil { + p.logger.Error().Err(err).Str("event_id", eventID).Msg("failed to mark read request reverted") + } +} diff --git a/universalClient/pushwatcher/read_event_processor_test.go b/universalClient/pushwatcher/read_event_processor_test.go new file mode 100644 index 00000000..5240143d --- /dev/null +++ b/universalClient/pushwatcher/read_event_processor_test.go @@ -0,0 +1,251 @@ +package pushwatcher + +import ( + "context" + "fmt" + "testing" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/pushchain/push-chain-node/universalClient/externalchains/common" + "github.com/pushchain/push-chain-node/universalClient/store" + ucallbacktypes "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +type fakeReadVoter struct { + votes map[string]*ucallbacktypes.ReadResult + txHash string + err error +} + +func (f *fakeReadVoter) VoteReadResult(ctx context.Context, requestID string, result *ucallbacktypes.ReadResult) (string, error) { + if f.err != nil { + return "", f.err + } + if f.votes == nil { + f.votes = make(map[string]*ucallbacktypes.ReadResult) + } + f.votes[requestID] = result + return f.txHash, nil +} + +type fakeDestClient struct { + result *ucallbacktypes.ReadResult + err error + notStarted bool +} + +func (f *fakeDestClient) Start(ctx context.Context) error { return nil } +func (f *fakeDestClient) Stop() error { return nil } +func (f *fakeDestClient) IsHealthy() bool { return true } +func (f *fakeDestClient) GetTxBuilder() (common.TxBuilder, error) { + return nil, fmt.Errorf("not supported") +} +func (f *fakeDestClient) GetReadRequestHandler() (common.ReadRequestHandler, error) { + if f.notStarted { + return nil, fmt.Errorf("client not started") + } + return f, nil +} +func (f *fakeDestClient) ExecuteRead(ctx context.Context, req *ucallbacktypes.ReadRequest) (*ucallbacktypes.ReadResult, error) { + return f.result, f.err +} + +type fakeChainResolver struct { + client common.ChainClient +} + +func (f *fakeChainResolver) GetClient(chainID string) (common.ChainClient, error) { + if f.client == nil { + return nil, fmt.Errorf("no client for %s", chainID) + } + return f.client, nil +} + +func testReadRequest() *ucallbacktypes.ReadRequest { + return &ucallbacktypes.ReadRequest{ + RequestId: "0xabc123", + DestinationChain: "eip155:11155111", + Query: []byte{0x01}, + MinConfirmations: 1, + DestinationBlockHeight: 100, + CreatedAtHeight: 7, + } +} + +func newTestReadEventProcessor(t *testing.T, voter readVoter, destClient common.ChainClient) (*ReadEventProcessor, *common.ChainStore) { + t.Helper() + database := newTestDB(t) + p, err := NewReadEventProcessor(voter, &fakeChainResolver{client: destClient}, nil, database, zerolog.Nop()) + require.NoError(t, err) + return p, common.NewChainStore(database) +} + +func seedReadRequest(t *testing.T, cs *common.ChainStore, req *ucallbacktypes.ReadRequest) *store.Event { + t.Helper() + event, err := convertReadRequestEvent(req) + require.NoError(t, err) + stored, err := cs.InsertEventIfNotExists(event) + require.NoError(t, err) + require.True(t, stored) + return event +} + +func assertStatus(t *testing.T, cs *common.ChainStore, eventID, status string) { + t.Helper() + rows, err := cs.UpdateEventStatus(eventID, status, status) + require.NoError(t, err) + assert.Equal(t, int64(1), rows, "event %s not in status %s", eventID, status) +} + +func TestReadEventProcessor_SuccessFlow(t *testing.T) { + req := testReadRequest() + result := &ucallbacktypes.ReadResult{ + Status: ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, + ResultData: []byte{0xaa}, + ObservedBlockHeight: 100, + } + voter := &fakeReadVoter{txHash: "VOTE_TX"} + p, cs := newTestReadEventProcessor(t, voter, &fakeDestClient{result: result}) + event := seedReadRequest(t, cs, req) + + require.NoError(t, p.HandleEvent(context.Background(), event)) + + require.Contains(t, voter.votes, req.RequestId) + assert.Equal(t, result, voter.votes[req.RequestId]) + assertStatus(t, cs, event.EventID, store.StatusCompleted) +} + +func TestReadEventProcessor_VoteFailureKeepsConfirmed(t *testing.T) { + req := testReadRequest() + voter := &fakeReadVoter{err: fmt.Errorf("MsgVoteReadResult not available")} + p, cs := newTestReadEventProcessor(t, voter, &fakeDestClient{result: &ucallbacktypes.ReadResult{Status: ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS}}) + event := seedReadRequest(t, cs, req) + + require.NoError(t, p.HandleEvent(context.Background(), event)) + + assertStatus(t, cs, event.EventID, store.StatusConfirmed) +} + +func TestReadEventProcessor_ExecutionFailureRetries(t *testing.T) { + req := testReadRequest() + voter := &fakeReadVoter{txHash: "VOTE_TX"} + p, cs := newTestReadEventProcessor(t, voter, &fakeDestClient{err: fmt.Errorf("rpc down")}) + event := seedReadRequest(t, cs, req) + + require.NoError(t, p.HandleEvent(context.Background(), event)) + + assert.Empty(t, voter.votes) + assertStatus(t, cs, event.EventID, store.StatusConfirmed) +} + +func TestReadEventProcessor_UnservedChainRetries(t *testing.T) { + req := testReadRequest() + voter := &fakeReadVoter{txHash: "VOTE_TX"} + p, cs := newTestReadEventProcessor(t, voter, nil) + event := seedReadRequest(t, cs, req) + + require.NoError(t, p.HandleEvent(context.Background(), event)) + + assert.Empty(t, voter.votes) + assertStatus(t, cs, event.EventID, store.StatusConfirmed) +} + +func TestReadEventProcessor_HandlerUnavailableRetries(t *testing.T) { + req := testReadRequest() + voter := &fakeReadVoter{txHash: "VOTE_TX"} + p, cs := newTestReadEventProcessor(t, voter, &fakeDestClient{notStarted: true}) + event := seedReadRequest(t, cs, req) + + require.NoError(t, p.HandleEvent(context.Background(), event)) + + assert.Empty(t, voter.votes) + assertStatus(t, cs, event.EventID, store.StatusConfirmed) +} + +func TestReadEventProcessor_CorruptEventReverted(t *testing.T) { + voter := &fakeReadVoter{txHash: "VOTE_TX"} + p, cs := newTestReadEventProcessor(t, voter, &fakeDestClient{result: &ucallbacktypes.ReadResult{Status: ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS}}) + + event := &store.Event{ + EventID: "corrupt-read", + Type: store.EventTypeReadRequest, + ConfirmationType: store.ConfirmationInstant, + Status: store.StatusConfirmed, + EventData: []byte("not json"), + } + stored, err := cs.InsertEventIfNotExists(event) + require.NoError(t, err) + require.True(t, stored) + + require.Error(t, p.HandleEvent(context.Background(), event)) + + assert.Empty(t, voter.votes) + assertStatus(t, cs, event.EventID, store.StatusReverted) +} + +func TestReadEventProcessor_ExpiredMarkedReverted(t *testing.T) { + req := testReadRequest() + req.ExpiryBlockHeight = 50 + voter := &fakeReadVoter{txHash: "VOTE_TX"} + p, cs := newTestReadEventProcessor(t, voter, &fakeDestClient{result: &ucallbacktypes.ReadResult{Status: ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS}}) + require.NoError(t, cs.UpdateChainHeight(100)) // push chain past expiry + event := seedReadRequest(t, cs, req) + + require.NoError(t, p.HandleEvent(context.Background(), event)) + + assert.Empty(t, voter.votes) + assertStatus(t, cs, event.EventID, store.StatusReverted) +} + +func TestReadEventProcessor_NotExpiredProcessesNormally(t *testing.T) { + req := testReadRequest() + req.ExpiryBlockHeight = 200 + voter := &fakeReadVoter{txHash: "VOTE_TX"} + p, cs := newTestReadEventProcessor(t, voter, &fakeDestClient{result: &ucallbacktypes.ReadResult{Status: ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS}}) + require.NoError(t, cs.UpdateChainHeight(100)) + event := seedReadRequest(t, cs, req) + + require.NoError(t, p.HandleEvent(context.Background(), event)) + + require.Contains(t, voter.votes, req.RequestId) + assertStatus(t, cs, event.EventID, store.StatusCompleted) +} + +func TestReadEventProcessor_Web2Dispatch(t *testing.T) { + req := testReadRequest() + req.DestinationChain = "web2:https" + result := &ucallbacktypes.ReadResult{Status: ucallbacktypes.ReadStatus_READ_STATUS_SUCCESS, ResultData: []byte{0xbb}} + + t.Run("dispatches to web2 handler", func(t *testing.T) { + database := newTestDB(t) + voter := &fakeReadVoter{txHash: "VOTE_TX"} + web2Handler := &fakeDestClient{result: result} + p, err := NewReadEventProcessor(voter, &fakeChainResolver{}, web2Handler, database, zerolog.Nop()) + require.NoError(t, err) + cs := common.NewChainStore(database) + event := seedReadRequest(t, cs, req) + + require.NoError(t, p.HandleEvent(context.Background(), event)) + + require.Contains(t, voter.votes, req.RequestId) + assert.Equal(t, result, voter.votes[req.RequestId]) + assertStatus(t, cs, event.EventID, store.StatusCompleted) + }) + + t.Run("no web2 handler retries", func(t *testing.T) { + database := newTestDB(t) + voter := &fakeReadVoter{txHash: "VOTE_TX"} + p, err := NewReadEventProcessor(voter, &fakeChainResolver{}, nil, database, zerolog.Nop()) + require.NoError(t, err) + cs := common.NewChainStore(database) + event := seedReadRequest(t, cs, req) + + require.NoError(t, p.HandleEvent(context.Background(), event)) + + assert.Empty(t, voter.votes) + assertStatus(t, cs, event.EventID, store.StatusConfirmed) + }) +} diff --git a/universalClient/store/models.go b/universalClient/store/models.go index 98ef87d8..b3cc331b 100644 --- a/universalClient/store/models.go +++ b/universalClient/store/models.go @@ -28,6 +28,7 @@ const ( EventTypeSignFundMigrate = "SIGN_FUND_MIGRATE" EventTypeInbound = "INBOUND" EventTypeOutbound = "OUTBOUND" + EventTypeReadRequest = "READ_REQUEST" ) // Confirmation type values. diff --git a/universalClient/tss/coordinator/coordinator_test.go b/universalClient/tss/coordinator/coordinator_test.go index 69cf0f26..b4ea3cd4 100644 --- a/universalClient/tss/coordinator/coordinator_test.go +++ b/universalClient/tss/coordinator/coordinator_test.go @@ -84,6 +84,9 @@ type coordMockChainClient struct { func (m *coordMockChainClient) Start(context.Context) error { return nil } func (m *coordMockChainClient) Stop() error { return nil } func (m *coordMockChainClient) IsHealthy() bool { return true } +func (m *coordMockChainClient) GetReadRequestHandler() (common.ReadRequestHandler, error) { + return nil, nil +} func (m *coordMockChainClient) GetTxBuilder() (common.TxBuilder, error) { if m.builderErr != nil { return nil, m.builderErr diff --git a/universalClient/tss/txbroadcaster/broadcaster_test.go b/universalClient/tss/txbroadcaster/broadcaster_test.go index 653d13d0..dae85fb3 100644 --- a/universalClient/tss/txbroadcaster/broadcaster_test.go +++ b/universalClient/tss/txbroadcaster/broadcaster_test.go @@ -79,9 +79,12 @@ func (m *mockTxBuilder) BroadcastFundMigrationTx(ctx context.Context, req *commo type mockChainClient struct{ builder *mockTxBuilder } -func (m *mockChainClient) Start(context.Context) error { return nil } -func (m *mockChainClient) Stop() error { return nil } -func (m *mockChainClient) IsHealthy() bool { return true } +func (m *mockChainClient) Start(context.Context) error { return nil } +func (m *mockChainClient) Stop() error { return nil } +func (m *mockChainClient) IsHealthy() bool { return true } +func (m *mockChainClient) GetReadRequestHandler() (common.ReadRequestHandler, error) { + return nil, nil +} func (m *mockChainClient) GetTxBuilder() (common.TxBuilder, error) { return m.builder, nil } func setupTestDB(t *testing.T) (*eventstore.Store, *gorm.DB) { diff --git a/universalClient/tss/txresolver/resolver_test.go b/universalClient/tss/txresolver/resolver_test.go index b7df913f..b13aec47 100644 --- a/universalClient/tss/txresolver/resolver_test.go +++ b/universalClient/tss/txresolver/resolver_test.go @@ -76,9 +76,12 @@ func (m *mockTxBuilder) BroadcastFundMigrationTx(ctx context.Context, req *commo type mockChainClient struct{ builder *mockTxBuilder } -func (m *mockChainClient) Start(context.Context) error { return nil } -func (m *mockChainClient) Stop() error { return nil } -func (m *mockChainClient) IsHealthy() bool { return true } +func (m *mockChainClient) Start(context.Context) error { return nil } +func (m *mockChainClient) Stop() error { return nil } +func (m *mockChainClient) IsHealthy() bool { return true } +func (m *mockChainClient) GetReadRequestHandler() (common.ReadRequestHandler, error) { + return nil, nil +} func (m *mockChainClient) GetTxBuilder() (common.TxBuilder, error) { return m.builder, nil } func setupTestDB(t *testing.T) (*eventstore.Store, *gorm.DB) { diff --git a/x/ucallback/README.md b/x/ucallback/README.md new file mode 100755 index 00000000..17c8d110 --- /dev/null +++ b/x/ucallback/README.md @@ -0,0 +1,3 @@ +# Example Module + +This is a module base generated with [`spawn`](https://github.com/rollchains/spawn). \ No newline at end of file diff --git a/x/ucallback/autocli.go b/x/ucallback/autocli.go new file mode 100755 index 00000000..fb13da76 --- /dev/null +++ b/x/ucallback/autocli.go @@ -0,0 +1,56 @@ +package module + +import ( + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + modulev1 "github.com/pushchain/push-chain-node/api/ucallback/v1" +) + +// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. +func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { + return &autocliv1.ModuleOptions{ + Query: &autocliv1.ServiceCommandDescriptor{ + Service: modulev1.Query_ServiceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "Params", + Use: "params", + Short: "Query the current consensus parameters", + }, + { + RpcMethod: "AllPendingReadRequests", + Use: "pending-read-requests", + Short: "List read requests awaiting an observation", + }, + { + RpcMethod: "UniversalRead", + Use: "universal-read ", + Short: "Query one read request by id", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "request_id"}}, + }, + { + RpcMethod: "ReadsByTx", + Use: "reads-by-tx ", + Short: "List every read requested by one Push transaction", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: "tx_hash"}}, + }, + }, + }, + Tx: &autocliv1.ServiceCommandDescriptor{ + Service: modulev1.Msg_ServiceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "UpdateParams", + Skip: false, // set to true if authority gated + }, + { + RpcMethod: "VoteReadResult", + Use: "vote-read-result ", + Short: "Vote on the observed outcome of a read request", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "request_id"}, + }, + }, + }, + }, + } +} diff --git a/x/ucallback/client/cli/query.go b/x/ucallback/client/cli/query.go new file mode 100755 index 00000000..3ac724db --- /dev/null +++ b/x/ucallback/client/cli/query.go @@ -0,0 +1,50 @@ +package cli + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +// !NOTE: Must enable in module.go (disabled in favor of autocli.go) + +func GetQueryCmd() *cobra.Command { + queryCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Querying commands for " + types.ModuleName, + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + queryCmd.AddCommand( + GetCmdParams(), + ) + return queryCmd +} + +func GetCmdParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Short: "Show all module params", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + res, err := queryClient.Params(cmd.Context(), &types.QueryParamsRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + flags.AddQueryFlagsToCmd(cmd) + return cmd +} diff --git a/x/ucallback/client/cli/tx.go b/x/ucallback/client/cli/tx.go new file mode 100755 index 00000000..6cdf69fd --- /dev/null +++ b/x/ucallback/client/cli/tx.go @@ -0,0 +1,71 @@ +package cli + +import ( + "strconv" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +// !NOTE: Must enable in module.go (disabled in favor of autocli.go) + +// NewTxCmd returns a root CLI command handler for certain modules +// transaction commands. +func NewTxCmd() *cobra.Command { + txCmd := &cobra.Command{ + Use: types.ModuleName, + Short: types.ModuleName + " subcommands.", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + txCmd.AddCommand( + MsgUpdateParams(), + ) + return txCmd +} + +// Returns a CLI command handler for registering a +// contract for the module. +func MsgUpdateParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "update-params [some-value]", + Short: "Update the params (must be submitted from the authority)", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + senderAddress := cliCtx.GetFromAddress() + + someValue, err := strconv.ParseBool(args[0]) + if err != nil { + return err + } + + msg := &types.MsgUpdateParams{ + Authority: senderAddress.String(), + Params: types.Params{ + SomeValue: someValue, + }, + } + + if err := msg.Validate(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(cliCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + return cmd +} diff --git a/x/ucallback/depinject.go b/x/ucallback/depinject.go new file mode 100755 index 00000000..26aa352a --- /dev/null +++ b/x/ucallback/depinject.go @@ -0,0 +1,66 @@ +package module + +import ( + "os" + + "github.com/cosmos/cosmos-sdk/codec" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" + + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + + "cosmossdk.io/core/address" + "cosmossdk.io/core/appmodule" + "cosmossdk.io/core/store" + "cosmossdk.io/depinject" + "cosmossdk.io/log" + + modulev1 "github.com/pushchain/push-chain-node/api/ucallback/module/v1" + "github.com/pushchain/push-chain-node/x/ucallback/keeper" + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +var _ appmodule.AppModule = AppModule{} + +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (am AppModule) IsOnePerModuleType() {} + +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} + +func init() { + appmodule.Register( + &modulev1.Module{}, + appmodule.Provide(ProvideModule), + ) +} + +type ModuleInputs struct { + depinject.In + + Cdc codec.Codec + StoreService store.KVStoreService + AddressCodec address.Codec + + StakingKeeper stakingkeeper.Keeper + SlashingKeeper slashingkeeper.Keeper + + UvalidatorKeeper types.UValidatorKeeper +} + +type ModuleOutputs struct { + depinject.Out + + Module appmodule.AppModule + Keeper keeper.Keeper +} + +func ProvideModule(in ModuleInputs) ModuleOutputs { + govAddr := authtypes.NewModuleAddress(govtypes.ModuleName).String() + + k := keeper.NewKeeper(in.Cdc, in.StoreService, log.NewLogger(os.Stderr), govAddr, in.UvalidatorKeeper) + m := NewAppModule(in.Cdc, k) + + return ModuleOutputs{Module: m, Keeper: k, Out: depinject.Out{}} +} diff --git a/x/ucallback/keeper/evm_hooks.go b/x/ucallback/keeper/evm_hooks.go new file mode 100644 index 00000000..d539556a --- /dev/null +++ b/x/ucallback/keeper/evm_hooks.go @@ -0,0 +1,77 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + evmtypes "github.com/cosmos/evm/x/vm/types" + "github.com/ethereum/go-ethereum/common" + core "github.com/ethereum/go-ethereum/core" + ethtypes "github.com/ethereum/go-ethereum/core/types" +) + +// EVMHooks implements the EVM post-processing hooks for x/ucallback. +// +// Runs after every EVM transaction, so the log filter in IngestReadRequests must +// stay tight: this hook sees traffic for the whole chain and must be a no-op for +// all of it except UniversalCallback's ReadRequested events. +type EVMHooks struct { + k Keeper +} + +// NewEVMHooks creates a new instance of EVMHooks. +func NewEVMHooks(k Keeper) evmtypes.EvmHooks { + return EVMHooks{k: k} +} + +// PostTxProcessing inspects the receipt and records a UniversalRead for every +// ReadRequested event the transaction emitted. +// +// Returning an error reverts the whole EVM transaction. That is the behaviour we +// want here: a ReadRequested log we cannot record is a request the user paid for +// that no validator would ever serve. Reverting returns their fee instead of +// stranding it. +func (h EVMHooks) PostTxProcessing( + ctx sdk.Context, + sender common.Address, + msg core.Message, + receipt *ethtypes.Receipt, +) error { + if receipt == nil || len(receipt.Logs) == 0 { + return nil + } + + protoReceipt := &evmtypes.MsgEthereumTxResponse{ + Hash: receipt.TxHash.Hex(), + GasUsed: receipt.GasUsed, + Logs: convertReceiptLogs(receipt.Logs), + } + + return h.k.IngestReadRequests(ctx, protoReceipt) +} + +func convertReceiptLogs(logs []*ethtypes.Log) []*evmtypes.Log { + out := make([]*evmtypes.Log, 0, len(logs)) + + for _, l := range logs { + out = append(out, &evmtypes.Log{ + Address: l.Address.Hex(), + Topics: convertTopics(l.Topics), + Data: l.Data, + BlockNumber: l.BlockNumber, + TxHash: l.TxHash.Hex(), + TxIndex: uint64(l.TxIndex), + BlockHash: l.BlockHash.Hex(), + Index: uint64(l.Index), + Removed: l.Removed, + }) + } + + return out +} + +func convertTopics(topics []common.Hash) []string { + out := make([]string, len(topics)) + for i, t := range topics { + out[i] = t.Hex() + } + return out +} diff --git a/x/ucallback/keeper/genesis.go b/x/ucallback/keeper/genesis.go new file mode 100644 index 00000000..fd9b5f3a --- /dev/null +++ b/x/ucallback/keeper/genesis.go @@ -0,0 +1,52 @@ +package keeper + +import ( + "context" + + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +// InitGenesis initializes the module's state from a genesis state. +// +// Only UniversalReads is imported. The PendingByExpiry and ReadsByTxHash indexes +// are rebuilt here from the records themselves, via SetUniversalRead — importing +// them separately would allow a genesis file to carry indexes that disagree with +// the records they point at. +func (k *Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) error { + if err := data.Params.Validate(); err != nil { + return err + } + + if err := k.Params.Set(ctx, data.Params); err != nil { + return err + } + + for _, entry := range data.UniversalReads { + if err := k.SetUniversalRead(ctx, entry.Value); err != nil { + return err + } + } + + return nil +} + +// ExportGenesis exports the module's state to a genesis state. +func (k *Keeper) ExportGenesis(ctx context.Context) *types.GenesisState { + params, err := k.Params.Get(ctx) + if err != nil { + panic(err) + } + + reads := []types.UniversalReadEntry{} + if err := k.UniversalReads.Walk(ctx, nil, func(key string, value types.UniversalRead) (bool, error) { + reads = append(reads, types.UniversalReadEntry{Key: key, Value: value}) + return false, nil + }); err != nil { + panic(err) + } + + return &types.GenesisState{ + Params: params, + UniversalReads: reads, + } +} diff --git a/x/ucallback/keeper/genesis_test.go b/x/ucallback/keeper/genesis_test.go new file mode 100755 index 00000000..210cd36a --- /dev/null +++ b/x/ucallback/keeper/genesis_test.go @@ -0,0 +1,22 @@ +package keeper_test + +import ( + "testing" + + "github.com/pushchain/push-chain-node/x/ucallback/types" + "github.com/stretchr/testify/require" +) + +func TestGenesis(t *testing.T) { + f := SetupTest(t) + + genesisState := &types.GenesisState{ + Params: types.DefaultParams(), + } + + f.k.InitGenesis(f.ctx, genesisState) + + got := f.k.ExportGenesis(f.ctx) + require.NotNil(t, got) + +} diff --git a/x/ucallback/keeper/ingest.go b/x/ucallback/keeper/ingest.go new file mode 100644 index 00000000..0877d739 --- /dev/null +++ b/x/ucallback/keeper/ingest.go @@ -0,0 +1,124 @@ +package keeper + +import ( + "context" + "fmt" + "math/big" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + evmtypes "github.com/cosmos/evm/x/vm/types" + + "github.com/pushchain/push-chain-node/x/ucallback/types" + uregistrytypes "github.com/pushchain/push-chain-node/x/uregistry/types" +) + +// IngestReadRequests records a UniversalRead for every ReadRequested event in the +// receipt. +// +// The two-part filter — log.Address must be UniversalCallback, topic0 must be +// ReadRequested — is what makes the decoded event trustworthy. Any contract can +// emit a log with the same topic0; only the system contract's address makes it +// ours. Dropping the address check would let anyone mint read requests. +func (k Keeper) IngestReadRequests(ctx context.Context, receipt *evmtypes.MsgEthereumTxResponse) error { + if receipt == nil || len(receipt.Logs) == 0 { + return nil + } + + sdkCtx := sdk.UnwrapSDKContext(ctx) + callbackAddr := strings.ToLower(uregistrytypes.SYSTEM_CONTRACTS["UNIVERSAL_CALLBACK"].Address) + + for _, lg := range receipt.Logs { + if lg.Removed { + continue + } + if strings.ToLower(lg.Address) != callbackAddr { + continue + } + if len(lg.Topics) == 0 || + !strings.EqualFold(lg.Topics[0], types.ReadRequestedEventSig.Hex()) { + continue + } + + event, err := types.DecodeReadRequestedFromLog(lg) + if err != nil { + return fmt.Errorf("failed to decode ReadRequested (tx %s log %d): %w", + receipt.Hash, lg.Index, err) + } + + if err := k.recordReadRequest(ctx, sdkCtx, event, receipt.Hash, lg.Index); err != nil { + return err + } + } + + return nil +} + +// recordReadRequest writes one decoded event as a PENDING UniversalRead. +func (k Keeper) recordReadRequest( + ctx context.Context, + sdkCtx sdk.Context, + event *types.ReadRequestedEvent, + txHash string, + logIndex uint64, +) error { + // requestId is derived on-chain from an incrementing nonce, so a repeat means + // the same log was replayed rather than a genuine second request. Keep the + // first record: it is the one validators may already be working from. + if k.HasUniversalRead(ctx, event.RequestID) { + k.Logger().Debug("read request already recorded, skipping", + "request_id", event.RequestID, "tx_hash", txHash) + return nil + } + + ur := types.UniversalRead{ + Id: event.RequestID, + Status: types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING, + Request: &types.ReadRequest{ + RequestId: event.RequestID, + DestinationChain: event.DestinationChain(), + Owner: event.Owner, + Query: event.Query, + MinConfirmations: uint32(event.MinConfirmations), + DestinationBlockHeight: event.BlockNumber, + ExpiryBlockHeight: event.ExpiryPushChainHeight, + // Not carried by the event — the height at which we observed it is the + // only honest answer, and it is what expiry is measured against. + CreatedAtHeight: uint64(sdkCtx.BlockHeight()), + CallbackTarget: event.CallbackTarget, + OriginalFunder: event.OriginalFunder, + FeesDeposited: bigOrZero(event.FeesDeposited), + MaxFee: bigOrZero(event.MaxFee), + RequestedTxHash: txHash, + RequestedLogIndex: logIndex, + }, + } + + if err := k.SetUniversalRead(ctx, ur); err != nil { + return fmt.Errorf("failed to record read request %s: %w", event.RequestID, err) + } + + k.Logger().Info("read request recorded", + "request_id", event.RequestID, + "destination_chain", ur.Request.DestinationChain, + "expiry_height", ur.Request.ExpiryBlockHeight, + "tx_hash", txHash, + "log_index", logIndex, + ) + + return nil +} + +// bigOrZero renders a *big.Int as a decimal string, tolerating nil. The proto +// carries these as strings because they are uint256 values that do not fit any +// protobuf integer type. +// +// Takes *big.Int rather than a String()-bearing interface on purpose: a nil +// *big.Int boxed into an interface is not itself nil, so the guard would miss it +// and String() would be called on a nil receiver. +func bigOrZero(v *big.Int) string { + if v == nil { + return "0" + } + return v.String() +} diff --git a/x/ucallback/keeper/ingest_test.go b/x/ucallback/keeper/ingest_test.go new file mode 100644 index 00000000..da08f0f1 --- /dev/null +++ b/x/ucallback/keeper/ingest_test.go @@ -0,0 +1,234 @@ +package keeper_test + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + evmtypes "github.com/cosmos/evm/x/vm/types" + + "github.com/pushchain/push-chain-node/x/ucallback/types" + uregistrytypes "github.com/pushchain/push-chain-node/x/uregistry/types" +) + +type acct struct { + ChainNamespace string + ChainId string + Owner []byte +} + +type spec struct { + Account acct + Query []byte + MinConfirmations uint16 + BlockNumber uint64 + ExpiryPushChainHeight uint64 + MaxFee *big.Int +} + +func readSpecArgs(t *testing.T) abi.Arguments { + t.Helper() + specType, err := abi.NewType("tuple", "", []abi.ArgumentMarshaling{ + {Name: "account", Type: "tuple", Components: []abi.ArgumentMarshaling{ + {Name: "chainNamespace", Type: "string"}, + {Name: "chainId", Type: "string"}, + {Name: "owner", Type: "bytes"}, + }}, + {Name: "query", Type: "bytes"}, + {Name: "minConfirmations", Type: "uint16"}, + {Name: "blockNumber", Type: "uint64"}, + {Name: "expiryPushChainHeight", Type: "uint64"}, + {Name: "maxFee", Type: "uint256"}, + }) + require.NoError(t, err) + u256, err := abi.NewType("uint256", "", nil) + require.NoError(t, err) + return abi.Arguments{{Type: specType}, {Type: u256}} +} + +// readLog builds a well-formed ReadRequested log emitted by the real system +// contract address. +func readLog(t *testing.T, requestID string, expiry uint64, index uint64) *evmtypes.Log { + t.Helper() + data, err := readSpecArgs(t).Pack(spec{ + Account: acct{ + ChainNamespace: "eip155", + ChainId: "11155111", + Owner: common.FromHex("0x1111111111111111111111111111111111111111"), + }, + Query: common.FromHex("0xdeadbeef"), + MinConfirmations: 6, + BlockNumber: 8_000_000, + ExpiryPushChainHeight: expiry, + MaxFee: big.NewInt(7), + }, big.NewInt(99)) + require.NoError(t, err) + + return &evmtypes.Log{ + Address: uregistrytypes.SYSTEM_CONTRACTS["UNIVERSAL_CALLBACK"].Address, + Topics: []string{ + types.ReadRequestedEventSig.Hex(), + common.HexToHash(requestID).Hex(), + common.HexToHash("0x2222222222222222222222222222222222222222").Hex(), + common.HexToHash("0x3333333333333333333333333333333333333333").Hex(), + }, + Data: data, + Index: index, + } +} + +func receipt(hash string, logs ...*evmtypes.Log) *evmtypes.MsgEthereumTxResponse { + return &evmtypes.MsgEthereumTxResponse{Hash: hash, Logs: logs} +} + +func TestIngestReadRequests_RecordsPendingRead(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(4242) + + lg := readLog(t, "0xaa", 900_000, 3) + require.NoError(t, f.k.IngestReadRequests(f.ctx, receipt("0xTX", lg))) + + ur, found := f.k.GetUniversalRead(f.ctx, lg.Topics[1]) + require.True(t, found) + require.Equal(t, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING, ur.Status) + + r := ur.Request + require.Equal(t, "eip155:11155111", r.DestinationChain, "namespace and id joined to CAIP-2") + require.Equal(t, common.FromHex("0x1111111111111111111111111111111111111111"), r.Owner) + require.Equal(t, common.FromHex("0xdeadbeef"), r.Query) + require.Equal(t, uint32(6), r.MinConfirmations) + require.Equal(t, uint64(8_000_000), r.DestinationBlockHeight) + require.Equal(t, uint64(900_000), r.ExpiryBlockHeight) + require.Equal(t, uint64(4242), r.CreatedAtHeight, "taken from the block, not the event") + require.Equal(t, "0xTX", r.RequestedTxHash) + require.Equal(t, uint64(3), r.RequestedLogIndex) + require.Equal(t, "99", r.FeesDeposited) + require.Equal(t, "7", r.MaxFee) +} + +// The address filter is the whole trust boundary: topic0 alone is forgeable by +// any contract, so a matching event from elsewhere must be ignored entirely. +func TestIngestReadRequests_IgnoresForeignContract(t *testing.T) { + f := SetupTest(t) + + lg := readLog(t, "0xaa", 900_000, 0) + lg.Address = "0x000000000000000000000000000000000000dEaD" + + require.NoError(t, f.k.IngestReadRequests(f.ctx, receipt("0xTX", lg))) + require.False(t, f.k.HasUniversalRead(f.ctx, lg.Topics[1]), + "a ReadRequested-shaped log from a foreign address must not mint a request") +} + +func TestIngestReadRequests_IgnoresUnrelatedLogs(t *testing.T) { + f := SetupTest(t) + + other := &evmtypes.Log{ + Address: uregistrytypes.SYSTEM_CONTRACTS["UNIVERSAL_CALLBACK"].Address, + Topics: []string{common.HexToHash("0xfeed").Hex()}, + Data: []byte{1, 2, 3}, + } + noTopics := &evmtypes.Log{ + Address: uregistrytypes.SYSTEM_CONTRACTS["UNIVERSAL_CALLBACK"].Address, + } + + require.NoError(t, f.k.IngestReadRequests(f.ctx, receipt("0xTX", other, noTopics))) + require.Empty(t, pendingIDs(t, f)) +} + +func TestIngestReadRequests_SkipsRemovedLogs(t *testing.T) { + f := SetupTest(t) + + lg := readLog(t, "0xaa", 900_000, 0) + lg.Removed = true + + require.NoError(t, f.k.IngestReadRequests(f.ctx, receipt("0xTX", lg))) + require.False(t, f.k.HasUniversalRead(f.ctx, lg.Topics[1])) +} + +// One transaction emitting several ReadRequested logs becomes several independent +// records that still reassemble as a batch. +func TestIngestReadRequests_Batch(t *testing.T) { + f := SetupTest(t) + + a := readLog(t, "0xaa", 900_000, 0) + b := readLog(t, "0xbb", 900_001, 1) + c := readLog(t, "0xcc", 900_002, 2) + + require.NoError(t, f.k.IngestReadRequests(f.ctx, receipt("0xBATCH", a, b, c))) + + res, err := f.queryServer.ReadsByTx(f.ctx, &types.QueryReadsByTxRequest{TxHash: "0xBATCH"}) + require.NoError(t, err) + require.Len(t, res.Reads, 3) + + for _, r := range res.Reads { + require.Equal(t, "0xBATCH", r.Request.RequestedTxHash) + require.Equal(t, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING, r.Status) + } + // log index is preserved per sibling, so each is individually addressable + require.ElementsMatch(t, []uint64{0, 1, 2}, + []uint64{res.Reads[0].Request.RequestedLogIndex, + res.Reads[1].Request.RequestedLogIndex, + res.Reads[2].Request.RequestedLogIndex}) +} + +// Replaying the same log must not overwrite progress already made on the request. +func TestIngestReadRequests_IsIdempotent(t *testing.T) { + f := SetupTest(t) + + lg := readLog(t, "0xaa", 900_000, 0) + require.NoError(t, f.k.IngestReadRequests(f.ctx, receipt("0xTX", lg))) + + // the request advances + ur, found := f.k.GetUniversalRead(f.ctx, lg.Topics[1]) + require.True(t, found) + ur.Status = types.UniversalReadStatus_UNIVERSAL_READ_STATUS_VOTING + ur.BallotKey = "ballot-1" + require.NoError(t, f.k.SetUniversalRead(f.ctx, ur)) + + // replay + require.NoError(t, f.k.IngestReadRequests(f.ctx, receipt("0xTX", lg))) + + again, found := f.k.GetUniversalRead(f.ctx, lg.Topics[1]) + require.True(t, found) + require.Equal(t, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_VOTING, again.Status, + "replay must not reset an in-flight request to PENDING") + require.Equal(t, "ballot-1", again.BallotKey) +} + +// An undecodable log from our own contract is a bug, not user error. Returning an +// error reverts the EVM tx so the funder keeps their fee rather than paying for a +// request no validator will ever see. +func TestIngestReadRequests_UndecodableIsAnError(t *testing.T) { + f := SetupTest(t) + + lg := readLog(t, "0xaa", 900_000, 0) + lg.Data = lg.Data[:len(lg.Data)/2] + + require.Error(t, f.k.IngestReadRequests(f.ctx, receipt("0xTX", lg))) + require.Empty(t, pendingIDs(t, f)) +} + +func TestIngestReadRequests_EmptyReceipt(t *testing.T) { + f := SetupTest(t) + require.NoError(t, f.k.IngestReadRequests(f.ctx, nil)) + require.NoError(t, f.k.IngestReadRequests(f.ctx, receipt("0xTX"))) + require.Empty(t, pendingIDs(t, f)) +} + +// Ingested reads are immediately visible to validators through the polling query. +func TestIngestReadRequests_VisibleToValidators(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(100) + + live := readLog(t, "0xaa", 500, 0) + dead := readLog(t, "0xbb", 50, 1) + + require.NoError(t, f.k.IngestReadRequests(f.ctx, receipt("0xTX", live, dead))) + + require.Equal(t, []string{live.Topics[1]}, pendingIDs(t, f), + "a request ingested already past its expiry is recorded but never offered") + require.True(t, f.k.HasUniversalRead(f.ctx, dead.Topics[1])) +} diff --git a/x/ucallback/keeper/keeper.go b/x/ucallback/keeper/keeper.go new file mode 100755 index 00000000..2a76416c --- /dev/null +++ b/x/ucallback/keeper/keeper.go @@ -0,0 +1,95 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/codec" + + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + "cosmossdk.io/collections" + storetypes "cosmossdk.io/core/store" + "cosmossdk.io/log" + + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +type Keeper struct { + cdc codec.BinaryCodec + + logger log.Logger + + // state management + Schema collections.Schema + Params collections.Item[types.Params] + + // UniversalReads is the canonical record for every read request, keyed by + // requestId. Indexes over it are added alongside the lookups they serve, and + // are always derived — never a source of truth. + UniversalReads collections.Map[string, types.UniversalRead] + + // PendingByExpiry holds (expiryHeight, requestId) for reads that have not + // settled — the module's in-flight set. Ordered composite key so the sweeper + // can range-scan by height. + PendingByExpiry collections.KeySet[collections.Pair[uint64, string]] + + // ReadsByTxHash holds (pushTxHash, requestId) so every read emitted by one + // Push transaction can be listed together. + ReadsByTxHash collections.KeySet[collections.Pair[string, string]] + + uvalidatorKeeper types.UValidatorKeeper + + authority string +} + +// NewKeeper creates a new Keeper instance +func NewKeeper( + cdc codec.BinaryCodec, + storeService storetypes.KVStoreService, + logger log.Logger, + authority string, + uvalidatorKeeper types.UValidatorKeeper, +) Keeper { + logger = logger.With(log.ModuleKey, "x/"+types.ModuleName) + + sb := collections.NewSchemaBuilder(storeService) + + if authority == "" { + authority = authtypes.NewModuleAddress(govtypes.ModuleName).String() + } + + k := Keeper{ + cdc: cdc, + logger: logger, + + Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)), + + UniversalReads: collections.NewMap( + sb, types.UniversalReadsKey, "universal_reads", + collections.StringKey, codec.CollValue[types.UniversalRead](cdc), + ), + PendingByExpiry: collections.NewKeySet( + sb, types.PendingByExpiryKey, "pending_by_expiry", + collections.PairKeyCodec(collections.Uint64Key, collections.StringKey), + ), + ReadsByTxHash: collections.NewKeySet( + sb, types.ReadsByTxHashKey, "reads_by_tx_hash", + collections.PairKeyCodec(collections.StringKey, collections.StringKey), + ), + + uvalidatorKeeper: uvalidatorKeeper, + authority: authority, + } + + schema, err := sb.Build() + if err != nil { + panic(err) + } + + k.Schema = schema + + return k +} + +func (k Keeper) Logger() log.Logger { + return k.logger +} diff --git a/x/ucallback/keeper/keeper_test.go b/x/ucallback/keeper/keeper_test.go new file mode 100755 index 00000000..8c742f7e --- /dev/null +++ b/x/ucallback/keeper/keeper_test.go @@ -0,0 +1,150 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + "cosmossdk.io/core/address" + "cosmossdk.io/log" + storetypes "cosmossdk.io/store/types" + + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + sdkaddress "github.com/cosmos/cosmos-sdk/codec/address" + "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/testutil/integration" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/pushchain/push-chain-node/app" + module "github.com/pushchain/push-chain-node/x/ucallback" + "github.com/pushchain/push-chain-node/x/ucallback/keeper" + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +var maccPerms = map[string][]string{ + authtypes.FeeCollectorName: nil, + stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + minttypes.ModuleName: {authtypes.Minter}, + govtypes.ModuleName: {authtypes.Burner}, +} + +type testFixture struct { + suite.Suite + + ctx sdk.Context + k keeper.Keeper + msgServer types.MsgServer + queryServer types.QueryServer + uvalidator *fakeUValidator + appModule *module.AppModule + + accountkeeper authkeeper.AccountKeeper + bankkeeper bankkeeper.BaseKeeper + stakingKeeper *stakingkeeper.Keeper + mintkeeper mintkeeper.Keeper + + addrs []sdk.AccAddress + govModAddr string +} + +func SetupTest(t *testing.T) *testFixture { + t.Helper() + f := new(testFixture) + + cfg := sdk.GetConfig() // do not seal, more set later + cfg.SetBech32PrefixForAccount(app.Bech32PrefixAccAddr, app.Bech32PrefixAccPub) + cfg.SetBech32PrefixForValidator(app.Bech32PrefixValAddr, app.Bech32PrefixValPub) + cfg.SetBech32PrefixForConsensusNode(app.Bech32PrefixConsAddr, app.Bech32PrefixConsPub) + cfg.SetCoinType(app.CoinType) + + validatorAddressCodec := sdkaddress.NewBech32Codec(app.Bech32PrefixValAddr) + accountAddressCodec := sdkaddress.NewBech32Codec(app.Bech32PrefixAccAddr) + consensusAddressCodec := sdkaddress.NewBech32Codec(app.Bech32PrefixConsAddr) + + // Base setup + logger := log.NewTestLogger(t) + encCfg := moduletestutil.MakeTestEncodingConfig() + + f.govModAddr = authtypes.NewModuleAddress(govtypes.ModuleName).String() + f.addrs = simtestutil.CreateIncrementalAccounts(3) + + keys := storetypes.NewKVStoreKeys(authtypes.ModuleName, banktypes.ModuleName, stakingtypes.ModuleName, minttypes.ModuleName, types.ModuleName) + f.ctx = sdk.NewContext(integration.CreateMultiStore(keys, logger), cmtproto.Header{}, false, logger) + + // Register SDK modules. + registerBaseSDKModules(logger, f, encCfg, keys, accountAddressCodec, validatorAddressCodec, consensusAddressCodec) + + // Setup Keeper. + f.uvalidator = newFakeUValidator() + f.k = keeper.NewKeeper(encCfg.Codec, runtime.NewKVStoreService(keys[types.ModuleName]), logger, f.govModAddr, f.uvalidator) + f.msgServer = keeper.NewMsgServerImpl(f.k) + f.queryServer = keeper.NewQuerier(f.k) + f.appModule = module.NewAppModule(encCfg.Codec, f.k) + + return f +} + +func registerModuleInterfaces(encCfg moduletestutil.TestEncodingConfig) { + authtypes.RegisterInterfaces(encCfg.InterfaceRegistry) + stakingtypes.RegisterInterfaces(encCfg.InterfaceRegistry) + banktypes.RegisterInterfaces(encCfg.InterfaceRegistry) + minttypes.RegisterInterfaces(encCfg.InterfaceRegistry) + + types.RegisterInterfaces(encCfg.InterfaceRegistry) +} + +func registerBaseSDKModules( + logger log.Logger, + f *testFixture, + encCfg moduletestutil.TestEncodingConfig, + keys map[string]*storetypes.KVStoreKey, + ac address.Codec, + validator address.Codec, + consensus address.Codec, +) { + registerModuleInterfaces(encCfg) + + // Auth Keeper. + f.accountkeeper = authkeeper.NewAccountKeeper( + encCfg.Codec, runtime.NewKVStoreService(keys[authtypes.StoreKey]), + authtypes.ProtoBaseAccount, + maccPerms, + ac, app.Bech32PrefixAccAddr, + f.govModAddr, + ) + + // Bank Keeper. + f.bankkeeper = bankkeeper.NewBaseKeeper( + encCfg.Codec, runtime.NewKVStoreService(keys[banktypes.StoreKey]), + f.accountkeeper, + nil, + f.govModAddr, logger, + ) + + // Staking Keeper. + f.stakingKeeper = stakingkeeper.NewKeeper( + encCfg.Codec, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), + f.accountkeeper, f.bankkeeper, f.govModAddr, + validator, + consensus, + ) + + // Mint Keeper. + f.mintkeeper = mintkeeper.NewKeeper( + encCfg.Codec, runtime.NewKVStoreService(keys[minttypes.StoreKey]), + f.stakingKeeper, f.accountkeeper, f.bankkeeper, + authtypes.FeeCollectorName, f.govModAddr, + ) +} diff --git a/x/ucallback/keeper/msg_server.go b/x/ucallback/keeper/msg_server.go new file mode 100755 index 00000000..81fde083 --- /dev/null +++ b/x/ucallback/keeper/msg_server.go @@ -0,0 +1,70 @@ +package keeper + +import ( + "context" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + "cosmossdk.io/errors" + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +type msgServer struct { + k Keeper +} + +var _ types.MsgServer = msgServer{} + +// NewMsgServerImpl returns an implementation of the module MsgServer interface. +func NewMsgServerImpl(keeper Keeper) types.MsgServer { + return &msgServer{k: keeper} +} + +func (ms msgServer) UpdateParams(ctx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + if ms.k.authority != msg.Authority { + return nil, errors.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", ms.k.authority, msg.Authority) + } + + return nil, ms.k.Params.Set(ctx, msg.Params) +} + +// VoteReadResult implements types.MsgServer. +// +// Eligibility is checked here rather than in the keeper: bonded-and-not-tombstoned +// is a property of the signer, and the same two guards front x/uexecutor's vote +// handlers. A validator that has been slashed out must not keep steering ballots. +func (ms msgServer) VoteReadResult(ctx context.Context, msg *types.MsgVoteReadResult) (*types.MsgVoteReadResultResponse, error) { + if msg.Result == nil { + return nil, fmt.Errorf("result is required") + } + + signerAccAddr, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, fmt.Errorf("invalid signer address: %w", err) + } + + isBonded, err := ms.k.uvalidatorKeeper.IsBondedUniversalValidator(ctx, msg.Signer) + if err != nil { + return nil, fmt.Errorf("failed to check bonded status for signer %s: %w", msg.Signer, err) + } + if !isBonded { + return nil, fmt.Errorf("universal validator for signer %s is not bonded", msg.Signer) + } + + isTombstoned, err := ms.k.uvalidatorKeeper.IsTombstonedUniversalValidator(ctx, msg.Signer) + if err != nil { + return nil, fmt.Errorf("failed to check tombstoned status for signer %s: %w", msg.Signer, err) + } + if isTombstoned { + return nil, fmt.Errorf("universal validator for signer %s is tombstoned", msg.Signer) + } + + finalized, err := ms.k.VoteReadResult(ctx, sdk.ValAddress(signerAccAddr), msg.RequestId, msg.Result) + if err != nil { + return nil, err + } + + return &types.MsgVoteReadResultResponse{Finalized: finalized}, nil +} diff --git a/x/ucallback/keeper/msg_server_test.go b/x/ucallback/keeper/msg_server_test.go new file mode 100755 index 00000000..87fb2088 --- /dev/null +++ b/x/ucallback/keeper/msg_server_test.go @@ -0,0 +1,56 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +func TestParams(t *testing.T) { + f := SetupTest(t) + require := require.New(t) + + testCases := []struct { + name string + request *types.MsgUpdateParams + err bool + }{ + { + name: "fail; invalid authority", + request: &types.MsgUpdateParams{ + Authority: f.addrs[0].String(), + Params: types.DefaultParams(), + }, + err: true, + }, + { + name: "success", + request: &types.MsgUpdateParams{ + Authority: f.govModAddr, + Params: types.DefaultParams(), + }, + err: false, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + _, err := f.msgServer.UpdateParams(f.ctx, tc.request) + + if tc.err { + require.Error(err) + } else { + require.NoError(err) + + r, err := f.queryServer.Params(f.ctx, &types.QueryParamsRequest{}) + require.NoError(err) + + require.EqualValues(&tc.request.Params, r.Params) + } + + }) + } +} diff --git a/x/ucallback/keeper/query_server.go b/x/ucallback/keeper/query_server.go new file mode 100755 index 00000000..4ed65af3 --- /dev/null +++ b/x/ucallback/keeper/query_server.go @@ -0,0 +1,117 @@ +package keeper + +import ( + "context" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "cosmossdk.io/collections" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" + + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +var _ types.QueryServer = Querier{} + +type Querier struct { + Keeper +} + +func NewQuerier(keeper Keeper) Querier { + return Querier{Keeper: keeper} +} + +func (k Querier) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + ctx := sdk.UnwrapSDKContext(c) + + p, err := k.Keeper.Params.Get(ctx) + if err != nil { + return nil, err + } + + return &types.QueryParamsResponse{Params: &p}, nil +} + +// AllPendingReadRequests implements types.QueryServer. +// +// Paginates the in-flight set (PendingByExpiry), which already excludes settled +// reads. Requests whose expiry height has passed are filtered out here too, rather +// than waiting for the sweeper to retire them: a validator that picked one up would +// spend a destination-chain read on work the contract may no longer accept. That +// makes the visible set correct regardless of how often the sweeper runs. +func (k Querier) AllPendingReadRequests(goCtx context.Context, req *types.QueryAllPendingReadRequestsRequest) (*types.QueryAllPendingReadRequestsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(goCtx) + height := uint64(ctx.BlockHeight()) + + reads, pageRes, err := query.CollectionFilteredPaginate( + ctx, k.Keeper.PendingByExpiry, req.Pagination, + func(key collections.Pair[uint64, string], _ collections.NoValue) (bool, error) { + return key.K1() > height, nil + }, + func(key collections.Pair[uint64, string], _ collections.NoValue) (types.UniversalRead, error) { + ur, found := k.Keeper.GetUniversalRead(ctx, key.K2()) + if !found { + // index entry with no record — skip rather than fail the page + return types.UniversalRead{}, nil + } + return ur, nil + }, + ) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &types.QueryAllPendingReadRequestsResponse{ + Reads: reads, + Pagination: pageRes, + }, nil +} + +// UniversalRead implements types.QueryServer. +// +// Serves a read at any point in its lifecycle, settled or not — this is the +// endpoint for "what happened to my request", so it must not filter the way +// AllPendingReadRequests does. +func (k Querier) UniversalRead(goCtx context.Context, req *types.QueryUniversalReadRequest) (*types.QueryUniversalReadResponse, error) { + if req == nil || req.RequestId == "" { + return nil, status.Error(codes.InvalidArgument, "request_id is required") + } + ctx := sdk.UnwrapSDKContext(goCtx) + + ur, found := k.Keeper.GetUniversalRead(ctx, req.RequestId) + if !found { + return nil, status.Errorf(codes.NotFound, "no read request with id %s", req.RequestId) + } + + return &types.QueryUniversalReadResponse{Read: ur}, nil +} + +// ReadsByTx implements types.QueryServer. +// +// Returns every read a single Push transaction requested, settled or not. Batches +// are the reason this exists: one transaction can emit several ReadRequested logs, +// each becoming an independent record that settles on its own schedule. +// +// Unpaginated by design — the fan-out is bounded by what fits in one transaction. +func (k Querier) ReadsByTx(goCtx context.Context, req *types.QueryReadsByTxRequest) (*types.QueryReadsByTxResponse, error) { + if req == nil || req.TxHash == "" { + return nil, status.Error(codes.InvalidArgument, "tx_hash is required") + } + ctx := sdk.UnwrapSDKContext(goCtx) + + reads := []types.UniversalRead{} + if err := k.Keeper.IterateReadsByTxHash(ctx, req.TxHash, func(ur types.UniversalRead) bool { + reads = append(reads, ur) + return true + }); err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &types.QueryReadsByTxResponse{Reads: reads}, nil +} diff --git a/x/ucallback/keeper/query_server_test.go b/x/ucallback/keeper/query_server_test.go new file mode 100644 index 00000000..b16c06d7 --- /dev/null +++ b/x/ucallback/keeper/query_server_test.go @@ -0,0 +1,131 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +func pendingIDs(t *testing.T, f *testFixture) []string { + t.Helper() + res, err := f.queryServer.AllPendingReadRequests(f.ctx, + &types.QueryAllPendingReadRequestsRequest{}) + require.NoError(t, err) + got := make([]string, 0, len(res.Reads)) + for _, r := range res.Reads { + got = append(got, r.Id) + } + return got +} + +// Only unsettled reads are listed. +func TestAllPendingReadRequests_ExcludesSettled(t *testing.T) { + f := SetupTest(t) + + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xpending", "0xTX", 500, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING))) + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xvoting", "0xTX", 500, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_VOTING))) + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xdone", "0xTX", 500, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_FULFILLED))) + + require.ElementsMatch(t, []string{"0xpending", "0xvoting"}, pendingIDs(t, f)) +} + +// A read past its expiry height is withheld even though the sweeper has not run, +// so validators never pick up work that can no longer be fulfilled in time. +func TestAllPendingReadRequests_WithholdsExpired(t *testing.T) { + f := SetupTest(t) + + f.ctx = f.ctx.WithBlockHeight(100) + + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xexpired", "0xTX", 50, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING))) + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xatheight", "0xTX", 100, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING))) + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xlive", "0xTX", 150, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING))) + + // still unsettled in state — the filter is at read time, not a mutation + require.True(t, f.k.HasUniversalRead(f.ctx, "0xexpired")) + + require.Equal(t, []string{"0xlive"}, pendingIDs(t, f), + "expiry height is exclusive: a read expiring at the current height is already too late") +} + +func TestAllPendingReadRequests_Empty(t *testing.T) { + f := SetupTest(t) + require.Empty(t, pendingIDs(t, f)) +} + +func TestAllPendingReadRequests_NilRequest(t *testing.T) { + f := SetupTest(t) + _, err := f.queryServer.AllPendingReadRequests(f.ctx, nil) + require.Error(t, err) +} + +// A read is served at any lifecycle stage — this endpoint answers "what happened +// to my request", so unlike the pending list it must not filter. +func TestUniversalRead_ServesSettledAndExpired(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(100) + + for id, st := range map[string]types.UniversalReadStatus{ + "0xpending": types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING, + "0xdone": types.UniversalReadStatus_UNIVERSAL_READ_STATUS_FULFILLED, + "0xgone": types.UniversalReadStatus_UNIVERSAL_READ_STATUS_EXPIRED, + } { + require.NoError(t, f.k.SetUniversalRead(f.ctx, newRead(id, "0xTX", 50, st))) + } + + for _, id := range []string{"0xpending", "0xdone", "0xgone"} { + res, err := f.queryServer.UniversalRead(f.ctx, + &types.QueryUniversalReadRequest{RequestId: id}) + require.NoError(t, err, id) + require.Equal(t, id, res.Read.Id) + } + + // ...even though only one of them is visible to validators + require.Empty(t, pendingIDs(t, f)) +} + +func TestUniversalRead_NotFound(t *testing.T) { + f := SetupTest(t) + + _, err := f.queryServer.UniversalRead(f.ctx, + &types.QueryUniversalReadRequest{RequestId: "0xmissing"}) + require.Error(t, err) + + _, err = f.queryServer.UniversalRead(f.ctx, &types.QueryUniversalReadRequest{}) + require.Error(t, err, "empty request_id is rejected, not treated as not-found") +} + +// The batch view returns siblings regardless of how each one settled. +func TestReadsByTx_ReturnsWholeBatch(t *testing.T) { + f := SetupTest(t) + + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xaaa", "0xBATCH", 500, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING))) + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xbbb", "0xBATCH", 500, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_FULFILLED))) + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xccc", "0xOTHER", 500, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING))) + + res, err := f.queryServer.ReadsByTx(f.ctx, &types.QueryReadsByTxRequest{TxHash: "0xBATCH"}) + require.NoError(t, err) + ids := []string{} + for _, r := range res.Reads { + ids = append(ids, r.Id) + } + require.ElementsMatch(t, []string{"0xaaa", "0xbbb"}, ids) + + // an unknown tx is an empty batch, not an error + res, err = f.queryServer.ReadsByTx(f.ctx, &types.QueryReadsByTxRequest{TxHash: "0xNOPE"}) + require.NoError(t, err) + require.Empty(t, res.Reads) + + _, err = f.queryServer.ReadsByTx(f.ctx, &types.QueryReadsByTxRequest{}) + require.Error(t, err) +} diff --git a/x/ucallback/keeper/universal_read.go b/x/ucallback/keeper/universal_read.go new file mode 100644 index 00000000..bfc127bf --- /dev/null +++ b/x/ucallback/keeper/universal_read.go @@ -0,0 +1,175 @@ +package keeper + +import ( + "context" + "fmt" + + "cosmossdk.io/collections" + + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +// isSettled reports whether a read has reached a terminal state and should no +// longer be swept for expiry. +func isSettled(s types.UniversalReadStatus) bool { + switch s { + case types.UniversalReadStatus_UNIVERSAL_READ_STATUS_FULFILLED, + types.UniversalReadStatus_UNIVERSAL_READ_STATUS_EXPIRED, + types.UniversalReadStatus_UNIVERSAL_READ_STATUS_FAILED: + return true + default: + return false + } +} + +// SetUniversalRead writes a read record. +// +// This is the only sanctioned way to mutate a UniversalRead. Indexes derived from +// the record are reconciled here, so writing k.UniversalReads directly will leave +// them stale — in particular the sweeper would keep expiring a read that has +// already settled. +func (k Keeper) SetUniversalRead(ctx context.Context, ur types.UniversalRead) error { + if ur.Id == "" { + return fmt.Errorf("universal read has empty request id") + } + + if err := k.UniversalReads.Set(ctx, ur.Id, ur); err != nil { + return err + } + + // pending-by-expiry: present only while unsettled + if ur.Request != nil { + key := collections.Join(ur.Request.ExpiryBlockHeight, ur.Id) + if isSettled(ur.Status) { + if err := k.PendingByExpiry.Remove(ctx, key); err != nil { + return err + } + } else if err := k.PendingByExpiry.Set(ctx, key); err != nil { + return err + } + + // reads-by-tx: written once, never removed — it is provenance, not state + if ur.Request.RequestedTxHash != "" { + if err := k.ReadsByTxHash.Set(ctx, + collections.Join(ur.Request.RequestedTxHash, ur.Id)); err != nil { + return err + } + } + } + + return nil +} + +// GetUniversalRead returns the read for requestId, if it exists. +func (k Keeper) GetUniversalRead(ctx context.Context, requestID string) (types.UniversalRead, bool) { + return k.getUniversalReadRaw(ctx, requestID) +} + +func (k Keeper) getUniversalReadRaw(ctx context.Context, requestID string) (types.UniversalRead, bool) { + ur, err := k.UniversalReads.Get(ctx, requestID) + if err != nil { + return types.UniversalRead{}, false + } + return ur, true +} + +// HasUniversalRead reports whether a read already exists. Ingest uses this to +// stay idempotent when the same log is seen twice. +func (k Keeper) HasUniversalRead(ctx context.Context, requestID string) bool { + has, err := k.UniversalReads.Has(ctx, requestID) + return err == nil && has +} + +// IterateExpiredBy calls fn for every unsettled read whose expiry height is at or +// below height, in ascending height order. The sweeper drives this. +// +// The key codec orders by expiryHeight first, so a plain ascending walk reaches +// every due entry before any that is not yet due — we break at the first key past +// height rather than constructing a cross-prefix range. +func (k Keeper) IterateExpiredBy(ctx context.Context, height uint64, fn func(types.UniversalRead) bool) error { + iter, err := k.PendingByExpiry.Iterate(ctx, nil) + if err != nil { + return err + } + defer iter.Close() + + for ; iter.Valid(); iter.Next() { + key, err := iter.Key() + if err != nil { + return err + } + if key.K1() > height { + break + } + ur, found := k.getUniversalReadRaw(ctx, key.K2()) + if !found { + continue + } + if !fn(ur) { + return nil + } + } + return nil +} + +// GetUniversalReadByBallot resolves a ballot key to its read. AfterBallotTerminal +// hands us only a ballot ID, and ballot IDs are one-way digests over the +// observation — not reversible — so this scans rather than indexes. +// +// The scan is over PendingByExpiry, not UniversalReads: entries leave that set the +// moment a read settles, so it holds only in-flight work. This mirrors uexecutor's +// ballot hook, which walks PendingInbounds for the same reason +// (x/uexecutor/keeper/ballot_hooks.go:86) — the pending set is small and transient, +// and this path only runs on terminal transitions. +// +// Returns false if no pending read owns the ballot: it may have already settled by +// another path, or the ballot may not belong to this module at all. +func (k Keeper) GetUniversalReadByBallot(ctx context.Context, ballotKey string) (types.UniversalRead, bool) { + if ballotKey == "" { + return types.UniversalRead{}, false + } + + var ( + found types.UniversalRead + ok bool + ) + err := k.PendingByExpiry.Walk(ctx, nil, func(key collections.Pair[uint64, string]) (bool, error) { + ur, exists := k.getUniversalReadRaw(ctx, key.K2()) + if exists && ur.BallotKey == ballotKey { + found, ok = ur, true + return true, nil + } + return false, nil + }) + if err != nil { + return types.UniversalRead{}, false + } + return found, ok +} + +// IterateReadsByTxHash calls fn for every read requested by the given Push tx. +// A single transaction can emit several ReadRequested logs; each is its own +// record, and this is how the batch is reassembled. +func (k Keeper) IterateReadsByTxHash(ctx context.Context, txHash string, fn func(types.UniversalRead) bool) error { + rng := collections.NewPrefixedPairRange[string, string](txHash) + iter, err := k.ReadsByTxHash.Iterate(ctx, rng) + if err != nil { + return err + } + defer iter.Close() + + for ; iter.Valid(); iter.Next() { + key, err := iter.Key() + if err != nil { + return err + } + ur, found := k.getUniversalReadRaw(ctx, key.K2()) + if !found { + continue + } + if !fn(ur) { + return nil + } + } + return nil +} diff --git a/x/ucallback/keeper/universal_read_test.go b/x/ucallback/keeper/universal_read_test.go new file mode 100644 index 00000000..c502d45a --- /dev/null +++ b/x/ucallback/keeper/universal_read_test.go @@ -0,0 +1,228 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +func newRead(id, txHash string, expiry uint64, status types.UniversalReadStatus) types.UniversalRead { + return types.UniversalRead{ + Id: id, + Status: status, + Request: &types.ReadRequest{ + RequestId: id, + DestinationChain: "eip155:1", + ExpiryBlockHeight: expiry, + RequestedTxHash: txHash, + }, + } +} + +func TestSetUniversalRead_RoundTrips(t *testing.T) { + f := SetupTest(t) + + require.False(t, f.k.HasUniversalRead(f.ctx, "0xaaa")) + + ur := newRead("0xaaa", "0xTX", 100, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING) + require.NoError(t, f.k.SetUniversalRead(f.ctx, ur)) + + require.True(t, f.k.HasUniversalRead(f.ctx, "0xaaa")) + got, found := f.k.GetUniversalRead(f.ctx, "0xaaa") + require.True(t, found) + require.Equal(t, "0xaaa", got.Id) + require.Equal(t, "eip155:1", got.Request.DestinationChain) + + _, found = f.k.GetUniversalRead(f.ctx, "0xmissing") + require.False(t, found) +} + +func TestSetUniversalRead_RejectsEmptyID(t *testing.T) { + f := SetupTest(t) + require.Error(t, f.k.SetUniversalRead(f.ctx, types.UniversalRead{})) +} + +func collectDueBy(t *testing.T, f *testFixture, height uint64) []string { + t.Helper() + var got []string + err := f.k.IterateExpiredBy(f.ctx, height, func(ur types.UniversalRead) bool { + got = append(got, ur.Id) + return true + }) + require.NoError(t, err) + return got +} + +// The sweep is bounded by height and ordered ascending. +func TestIterateExpiredBy_RespectsHeight(t *testing.T) { + f := SetupTest(t) + + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xlow", "0xTX", 50, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING))) + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xmid", "0xTX", 100, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_VOTING))) + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xhigh", "0xTX", 150, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING))) + + require.Equal(t, []string{"0xlow"}, collectDueBy(t, f, 50)) + require.Equal(t, []string{"0xlow", "0xmid"}, collectDueBy(t, f, 100), "ascending by expiry height") + require.Equal(t, []string{"0xlow", "0xmid", "0xhigh"}, collectDueBy(t, f, 999)) +} + +// Settling a read removes it from the in-flight set; the record itself remains. +func TestSetUniversalRead_SettledLeavesInFlightSet(t *testing.T) { + f := SetupTest(t) + + ur := newRead("0xaaa", "0xTX", 100, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING) + require.NoError(t, f.k.SetUniversalRead(f.ctx, ur)) + require.Equal(t, []string{"0xaaa"}, collectDueBy(t, f, 100)) + + ur.Status = types.UniversalReadStatus_UNIVERSAL_READ_STATUS_FULFILLED + require.NoError(t, f.k.SetUniversalRead(f.ctx, ur)) + + require.Empty(t, collectDueBy(t, f, 999), "settled reads are not swept") + require.True(t, f.k.HasUniversalRead(f.ctx, "0xaaa"), "the record survives") +} + +func collectByTx(t *testing.T, f *testFixture, txHash string) []string { + t.Helper() + var got []string + err := f.k.IterateReadsByTxHash(f.ctx, txHash, func(ur types.UniversalRead) bool { + got = append(got, ur.Id) + return true + }) + require.NoError(t, err) + return got +} + +// One Push tx emitting several ReadRequested logs produces several independent +// records that are still reassemblable as a batch. +func TestSetUniversalRead_BatchedRequestsShareTxHash(t *testing.T) { + f := SetupTest(t) + + for _, id := range []string{"0xaaa", "0xbbb", "0xccc"} { + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead(id, "0xBATCH", 100, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING))) + } + // a read from a different tx must not leak into the batch + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xddd", "0xOTHER", 100, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING))) + + require.ElementsMatch(t, []string{"0xaaa", "0xbbb", "0xccc"}, collectByTx(t, f, "0xBATCH")) + require.Equal(t, []string{"0xddd"}, collectByTx(t, f, "0xOTHER")) +} + +// Siblings from one batch settle independently — one FULFILLED, one still pending. +func TestSetUniversalRead_BatchSiblingsSettleIndependently(t *testing.T) { + f := SetupTest(t) + + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xaaa", "0xBATCH", 100, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING))) + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xbbb", "0xBATCH", 100, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING))) + + // settle only one of them + settled := newRead("0xaaa", "0xBATCH", 100, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_FULFILLED) + require.NoError(t, f.k.SetUniversalRead(f.ctx, settled)) + + // the settled one drops out of the expiry sweep, its sibling does not + require.Equal(t, []string{"0xbbb"}, collectDueBy(t, f, 100)) + // but both remain listed under the batch — reads-by-tx is provenance, not state + require.ElementsMatch(t, []string{"0xaaa", "0xbbb"}, collectByTx(t, f, "0xBATCH")) +} + +// Repointing a read's ballot key must not leave the old key resolvable. +func TestGetUniversalReadByBallot_Repointed(t *testing.T) { + f := SetupTest(t) + + ur := newRead("0xaaa", "0xTX", 100, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING) + ur.BallotKey = "ballot-old" + require.NoError(t, f.k.SetUniversalRead(f.ctx, ur)) + + ur.BallotKey = "ballot-new" + require.NoError(t, f.k.SetUniversalRead(f.ctx, ur)) + + _, found := f.k.GetUniversalReadByBallot(f.ctx, "ballot-old") + require.False(t, found, "the old ballot key must no longer resolve") + + byNew, found := f.k.GetUniversalReadByBallot(f.ctx, "ballot-new") + require.True(t, found) + require.Equal(t, "0xaaa", byNew.Id) +} + +// The lookup scans the in-flight set, so a settled read is deliberately NOT +// findable by ballot. The ballot terminal hook must treat "not found" as +// "already handled", exactly as uexecutor's hook does. +func TestGetUniversalReadByBallot_SettledReadIsNotFound(t *testing.T) { + f := SetupTest(t) + + ur := newRead("0xaaa", "0xTX", 100, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING) + ur.BallotKey = "ballot-1" + require.NoError(t, f.k.SetUniversalRead(f.ctx, ur)) + + _, found := f.k.GetUniversalReadByBallot(f.ctx, "ballot-1") + require.True(t, found, "resolvable while in flight") + + ur.Status = types.UniversalReadStatus_UNIVERSAL_READ_STATUS_FULFILLED + require.NoError(t, f.k.SetUniversalRead(f.ctx, ur)) + + _, found = f.k.GetUniversalReadByBallot(f.ctx, "ballot-1") + require.False(t, found, "settled reads leave the in-flight set") + + // the record itself is untouched — only the index dropped it + got, ok := f.k.GetUniversalRead(f.ctx, "0xaaa") + require.True(t, ok) + require.Equal(t, "ballot-1", got.BallotKey) +} + +// Only the read owning the ballot is returned, never a sibling sharing the scan. +func TestGetUniversalReadByBallot_PicksTheRightRead(t *testing.T) { + f := SetupTest(t) + + for i, id := range []string{"0xaaa", "0xbbb", "0xccc"} { + ur := newRead(id, "0xBATCH", uint64(100+i), + types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING) + ur.BallotKey = "ballot-" + id + require.NoError(t, f.k.SetUniversalRead(f.ctx, ur)) + } + + got, found := f.k.GetUniversalReadByBallot(f.ctx, "ballot-0xbbb") + require.True(t, found) + require.Equal(t, "0xbbb", got.Id) + + _, found = f.k.GetUniversalReadByBallot(f.ctx, "ballot-unknown") + require.False(t, found) +} + +// Genesis round-trips records, and rebuilds every index from them. +func TestGenesis_RoundTripRebuildsIndexes(t *testing.T) { + f := SetupTest(t) + require.NoError(t, f.k.InitGenesis(f.ctx, types.DefaultGenesis())) + + pending := newRead("0xaaa", "0xTX", 100, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING) + pending.BallotKey = "ballot-1" + require.NoError(t, f.k.SetUniversalRead(f.ctx, pending)) + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead("0xbbb", "0xTX", 100, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_FULFILLED))) + + exported := f.k.ExportGenesis(f.ctx) + require.Len(t, exported.UniversalReads, 2) + + // re-import into a clean fixture + g := SetupTest(t) + require.NoError(t, g.k.InitGenesis(g.ctx, exported)) + + _, found := g.k.GetUniversalRead(g.ctx, "0xaaa") + require.True(t, found) + + // indexes are rebuilt, not imported + byBallot, found := g.k.GetUniversalReadByBallot(g.ctx, "ballot-1") + require.True(t, found) + require.Equal(t, "0xaaa", byBallot.Id) + + require.ElementsMatch(t, []string{"0xaaa", "0xbbb"}, collectByTx(t, g, "0xTX")) + require.Equal(t, []string{"0xaaa"}, collectDueBy(t, g, 100), + "only the unsettled read is pending after re-import") +} diff --git a/x/ucallback/keeper/uvalidator_fake_test.go b/x/ucallback/keeper/uvalidator_fake_test.go new file mode 100644 index 00000000..257c84c8 --- /dev/null +++ b/x/ucallback/keeper/uvalidator_fake_test.go @@ -0,0 +1,124 @@ +package keeper_test + +import ( + "context" + "fmt" + + "github.com/pushchain/push-chain-node/x/ucallback/types" + uvalidatortypes "github.com/pushchain/push-chain-node/x/uvalidator/types" +) + +// fakeUValidator is an in-memory stand-in for x/uvalidator. +// +// It tallies votes for real rather than returning a canned isFinalized, because +// the behaviour under test is precisely that two validators reporting different +// observations land on different ballots and neither reaches quorum. A stub that +// ignored the ballot key could not distinguish that from success. +type fakeUValidator struct { + voters []string + bonded map[string]bool + tombstoned map[string]bool + + ballots map[string]*fakeBallot + + // set to force an error out of the corresponding call + votersErr error + voteErr error +} + +type fakeBallot struct { + observationType uvalidatortypes.BallotObservationType + votes map[string]uvalidatortypes.VoteResult + finalized bool + expiryBlocks int64 +} + +var _ types.UValidatorKeeper = (*fakeUValidator)(nil) + +func newFakeUValidator(voters ...string) *fakeUValidator { + f := &fakeUValidator{ + voters: voters, + bonded: map[string]bool{}, + tombstoned: map[string]bool{}, + ballots: map[string]*fakeBallot{}, + } + for _, v := range voters { + f.bonded[v] = true + } + return f +} + +func (f *fakeUValidator) IsBondedUniversalValidator(_ context.Context, v string) (bool, error) { + return f.bonded[v], nil +} + +func (f *fakeUValidator) IsTombstonedUniversalValidator(_ context.Context, v string) (bool, error) { + return f.tombstoned[v], nil +} + +func (f *fakeUValidator) GetEligibleVoters(_ context.Context) ([]uvalidatortypes.UniversalValidator, error) { + if f.votersErr != nil { + return nil, f.votersErr + } + out := make([]uvalidatortypes.UniversalValidator, 0, len(f.voters)) + for _, v := range f.voters { + out = append(out, uvalidatortypes.UniversalValidator{ + IdentifyInfo: &uvalidatortypes.IdentityInfo{CoreValidatorAddress: v}, + }) + } + return out, nil +} + +func (f *fakeUValidator) VoteOnBallot( + _ context.Context, + id string, + ballotType uvalidatortypes.BallotObservationType, + voter string, + voteResult uvalidatortypes.VoteResult, + _ []string, + votesNeeded int64, + expiryAfterBlocks int64, +) (uvalidatortypes.Ballot, bool, bool, error) { + if f.voteErr != nil { + return uvalidatortypes.Ballot{}, false, false, f.voteErr + } + + b, existed := f.ballots[id] + if !existed { + b = &fakeBallot{ + observationType: ballotType, + votes: map[string]uvalidatortypes.VoteResult{}, + expiryBlocks: expiryAfterBlocks, + } + f.ballots[id] = b + } + + if b.finalized { + return uvalidatortypes.Ballot{Id: id}, true, false, nil + } + if _, dup := b.votes[voter]; dup { + return uvalidatortypes.Ballot{Id: id}, false, false, + fmt.Errorf("validator %s already voted on ballot %s", voter, id) + } + + b.votes[voter] = voteResult + b.finalized = int64(len(b.votes)) >= votesNeeded + + return uvalidatortypes.Ballot{Id: id}, b.finalized, !existed, nil +} + +// ballotCount reports how many distinct ballots have been opened — the signal that +// validators diverged on what they observed. +func (f *fakeUValidator) ballotCount() int { return len(f.ballots) } + +// expiryOf returns the relative expiry a ballot was created with. +func (f *fakeUValidator) expiryOf(id string) int64 { + b, ok := f.ballots[id] + if !ok { + return -1 + } + return b.expiryBlocks +} + +// errTest is a sentinel for injecting failures into the fake. +var errTest = fmt.Errorf("injected test failure") diff --git a/x/ucallback/keeper/voting.go b/x/ucallback/keeper/voting.go new file mode 100644 index 00000000..042dc692 --- /dev/null +++ b/x/ucallback/keeper/voting.go @@ -0,0 +1,162 @@ +package keeper + +import ( + "context" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/pushchain/push-chain-node/x/ucallback/types" + uvalidatortypes "github.com/pushchain/push-chain-node/x/uvalidator/types" +) + +// VoteOnReadBallot casts one validator's vote on the ballot for (requestID, result) +// and reports whether that vote carried it to quorum. +// +// Mirrors x/uexecutor's VoteOnOutboundBallot for the threshold and voter set, but +// not for expiry: the ballot is given the request's own deadline rather than +// uexecutor's inert 100M blocks, so the two cannot disagree about when the request +// is over. +func (k Keeper) VoteOnReadBallot( + ctx context.Context, + universalValidator sdk.ValAddress, + requestID string, + result *types.ReadResult, + expiryHeight uint64, +) (ballotKey string, isFinalized bool, isNew bool, err error) { + ballotKey, err = types.GetReadBallotKey(requestID, result) + if err != nil { + return "", false, false, err + } + + voters, err := k.uvalidatorKeeper.GetEligibleVoters(ctx) + if err != nil { + return "", false, false, err + } + if len(voters) == 0 { + return "", false, false, fmt.Errorf("no eligible universal validators") + } + + // votesNeeded = floor(2/3 * n) + 1, i.e. a strict >2/3 majority, matching + // tendermint and every other ballot on this chain. + votesNeeded := (types.VotesThresholdNumerator*len(voters))/types.VotesThresholdDenominator + 1 + + voterAddrs := make([]string, len(voters)) + for i, v := range voters { + voterAddrs[i] = v.IdentifyInfo.CoreValidatorAddress + } + + expiryAfterBlocks := types.BallotExpiryAfterBlocks( + expiryHeight, sdk.UnwrapSDKContext(ctx).BlockHeight()) + + k.Logger().Debug("voting on read ballot", + "ballot_key", ballotKey, + "request_id", requestID, + "validator", universalValidator.String(), + "total_validators", len(voters), + "votes_needed", votesNeeded, + "expiry_height", expiryHeight, + "expiry_after_blocks", expiryAfterBlocks, + ) + + _, isFinalized, isNew, err = k.uvalidatorKeeper.VoteOnBallot( + ctx, + ballotKey, + uvalidatortypes.BallotObservationType_BALLOT_OBSERVATION_TYPE_READ_RESULT, + universalValidator.String(), + // Always SUCCESS: disagreement is expressed by landing on a different + // ballot key, not by voting FAILURE on a shared one. A FAILURE vote here + // would mean "this exact observation is wrong", which no validator is in a + // position to assert — it only knows what it observed itself. + uvalidatortypes.VoteResult_VOTE_RESULT_SUCCESS, + voterAddrs, + int64(votesNeeded), + expiryAfterBlocks, + ) + if err != nil { + return "", false, false, err + } + + if isNew { + k.Logger().Debug("read ballot created", "ballot_key", ballotKey, "request_id", requestID) + } + if isFinalized { + k.Logger().Info("read ballot finalized", "ballot_key", ballotKey, "request_id", requestID) + } + + return ballotKey, isFinalized, isNew, nil +} + +// VoteReadResult records a universal validator's observation of a read request. +// +// Reaching quorum here does NOT fulfil the request — it only settles what was +// observed. The fulfilment EVM call is driven by the ballot terminal hook (C7), so +// that it runs exactly once no matter which validator's vote happened to be the +// deciding one. +func (k Keeper) VoteReadResult( + ctx context.Context, + universalValidator sdk.ValAddress, + requestID string, + result *types.ReadResult, +) (bool, error) { + if result == nil { + return false, fmt.Errorf("read result is required") + } + + ur, found := k.GetUniversalRead(ctx, requestID) + if !found { + return false, fmt.Errorf("read request not found: %s", requestID) + } + + // Only unsettled requests accept votes. Without this a validator could keep + // voting on a request that already fulfilled, creating ballots that the + // terminal hook would then try to act on a second time. + if isSettled(ur.Status) { + return false, fmt.Errorf("read request %s is already %s", requestID, ur.Status) + } + + if ur.Request == nil { + return false, fmt.Errorf("read request %s has no request body", requestID) + } + + // Reject votes on a request whose deadline has passed. AllPendingReadRequests + // already withholds these, so an honest validator will not be voting on one — + // but the query is a convenience, not the enforcement point. + sdkCtx := sdk.UnwrapSDKContext(ctx) + if ur.Request.ExpiryBlockHeight <= uint64(sdkCtx.BlockHeight()) { + return false, fmt.Errorf("read request %s expired at height %d", + requestID, ur.Request.ExpiryBlockHeight) + } + + // Cache the vote so a failure partway through leaves no half-written ballot. + tmpCtx, commit := sdkCtx.CacheContext() + + ballotKey, isFinalized, _, err := k.VoteOnReadBallot( + tmpCtx, universalValidator, requestID, result, ur.Request.ExpiryBlockHeight) + if err != nil { + return false, err + } + + // The record follows the ballot that reached quorum, not the first ballot + // opened. Until one finalizes, ballot_key points at whichever observation this + // validator's vote most recently landed on. + ur.Status = types.UniversalReadStatus_UNIVERSAL_READ_STATUS_VOTING + ur.BallotKey = ballotKey + if isFinalized { + ur.Result = result + } + if err := k.SetUniversalRead(tmpCtx, ur); err != nil { + return false, err + } + + commit() + + k.Logger().Info("read result vote recorded", + "request_id", requestID, + "validator", universalValidator.String(), + "ballot_key", ballotKey, + "finalized", isFinalized, + ) + + return isFinalized, nil +} diff --git a/x/ucallback/keeper/voting_test.go b/x/ucallback/keeper/voting_test.go new file mode 100644 index 00000000..e323ab0b --- /dev/null +++ b/x/ucallback/keeper/voting_test.go @@ -0,0 +1,289 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +func obs(data byte) *types.ReadResult { + return &types.ReadResult{ + Status: types.ReadStatus_READ_STATUS_SUCCESS, + ResultData: []byte{data}, + ObservedBlockHeight: 8_000_000, + ObservedBlockHash: []byte{0xbe, 0xef}, + } +} + +// seedVoters configures n eligible validators and returns their val addresses. +func seedVoters(t *testing.T, f *testFixture, n int) []sdk.ValAddress { + t.Helper() + addrs := make([]sdk.ValAddress, n) + names := make([]string, n) + for i := 0; i < n; i++ { + addrs[i] = sdk.ValAddress(f.addrs[i%len(f.addrs)]) + // keep them distinct even when recycling the base accounts + names[i] = addrs[i].String() + string(rune('a'+i)) + addrs[i] = sdk.ValAddress(names[i]) + } + f.uvalidator.voters = names + for _, nm := range names { + f.uvalidator.bonded[nm] = true + } + return addrs +} + +func seedRead(t *testing.T, f *testFixture, id string, expiry uint64) { + t.Helper() + require.NoError(t, f.k.SetUniversalRead(f.ctx, + newRead(id, "0xTX", expiry, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING))) +} + +// A single vote below quorum moves the request to VOTING and attaches a ballot, +// but does not settle it. +func TestVoteReadResult_FirstVoteDoesNotFinalize(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(10) + v := seedVoters(t, f, 4) + seedRead(t, f, "0xaa", 500) + + finalized, err := f.k.VoteReadResult(f.ctx, v[0], "0xaa", obs(0x01)) + require.NoError(t, err) + require.False(t, finalized, "1 of 4 is below the >2/3 threshold") + + ur, found := f.k.GetUniversalRead(f.ctx, "0xaa") + require.True(t, found) + require.Equal(t, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_VOTING, ur.Status) + require.NotEmpty(t, ur.BallotKey) + require.Nil(t, ur.Result, "result is only attached once the ballot finalizes") + + // still offered to validators — the rest have not voted yet + require.Equal(t, []string{"0xaa"}, pendingIDs(t, f)) +} + +// Agreement on the same observation reaches quorum at floor(2/3n)+1. +func TestVoteReadResult_QuorumFinalizes(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(10) + v := seedVoters(t, f, 4) // votesNeeded = (2*4)/3 + 1 = 3 + seedRead(t, f, "0xaa", 500) + + for i := 0; i < 2; i++ { + finalized, err := f.k.VoteReadResult(f.ctx, v[i], "0xaa", obs(0x01)) + require.NoError(t, err) + require.False(t, finalized, "vote %d must not finalize", i+1) + } + + finalized, err := f.k.VoteReadResult(f.ctx, v[2], "0xaa", obs(0x01)) + require.NoError(t, err) + require.True(t, finalized, "third of four carries the ballot") + + ur, found := f.k.GetUniversalRead(f.ctx, "0xaa") + require.True(t, found) + require.NotNil(t, ur.Result, "the winning observation is attached") + require.Equal(t, []byte{0x01}, ur.Result.ResultData) + + require.Equal(t, 1, f.uvalidator.ballotCount(), "agreement means one ballot") +} + +// Divergent observations open separate ballots and neither reaches quorum. This is +// the core property of the design: agreement is expressed by arriving at the same +// key, so disagreement simply fails to accumulate. +func TestVoteReadResult_DivergentObservationsSplitBallots(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(10) + v := seedVoters(t, f, 4) + seedRead(t, f, "0xaa", 500) + + for i, data := range []byte{0x01, 0x02, 0x03} { + finalized, err := f.k.VoteReadResult(f.ctx, v[i], "0xaa", obs(data)) + require.NoError(t, err) + require.False(t, finalized, "observation %d must not finalize alone", i) + } + + require.Equal(t, 3, f.uvalidator.ballotCount(), + "three distinct observations must produce three ballots") + + ur, _ := f.k.GetUniversalRead(f.ctx, "0xaa") + require.Nil(t, ur.Result, "no observation won, so none is recorded") + require.Equal(t, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_VOTING, ur.Status) +} + +// A minority that diverges cannot stop the majority from finalizing. +func TestVoteReadResult_MinorityDivergenceDoesNotBlock(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(10) + v := seedVoters(t, f, 4) + seedRead(t, f, "0xaa", 500) + + _, err := f.k.VoteReadResult(f.ctx, v[0], "0xaa", obs(0xff)) // the outlier + require.NoError(t, err) + + for i := 1; i <= 2; i++ { + _, err := f.k.VoteReadResult(f.ctx, v[i], "0xaa", obs(0x01)) + require.NoError(t, err) + } + finalized, err := f.k.VoteReadResult(f.ctx, v[3], "0xaa", obs(0x01)) + require.NoError(t, err) + require.True(t, finalized) + + ur, _ := f.k.GetUniversalRead(f.ctx, "0xaa") + require.Equal(t, []byte{0x01}, ur.Result.ResultData, "the majority observation wins") +} + +func TestVoteReadResult_RejectsUnknownRequest(t *testing.T) { + f := SetupTest(t) + v := seedVoters(t, f, 4) + + _, err := f.k.VoteReadResult(f.ctx, v[0], "0xmissing", obs(0x01)) + require.ErrorContains(t, err, "not found") +} + +// Once settled, further votes must be refused — otherwise the terminal hook could +// be driven a second time. +func TestVoteReadResult_RejectsSettled(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(10) + v := seedVoters(t, f, 4) + + for _, st := range []types.UniversalReadStatus{ + types.UniversalReadStatus_UNIVERSAL_READ_STATUS_FULFILLED, + types.UniversalReadStatus_UNIVERSAL_READ_STATUS_EXPIRED, + types.UniversalReadStatus_UNIVERSAL_READ_STATUS_FAILED, + } { + id := "0x" + st.String() + require.NoError(t, f.k.SetUniversalRead(f.ctx, newRead(id, "0xTX", 500, st))) + _, err := f.k.VoteReadResult(f.ctx, v[0], id, obs(0x01)) + require.ErrorContains(t, err, "already", "status %s must reject votes", st) + } +} + +// Past its deadline a request stops accepting votes, independently of whether the +// sweeper has retired it yet. +func TestVoteReadResult_RejectsExpired(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(100) + v := seedVoters(t, f, 4) + + seedRead(t, f, "0xpast", 50) + _, err := f.k.VoteReadResult(f.ctx, v[0], "0xpast", obs(0x01)) + require.ErrorContains(t, err, "expired") + + // exactly at the expiry height is already too late, matching the query filter + seedRead(t, f, "0xnow", 100) + _, err = f.k.VoteReadResult(f.ctx, v[0], "0xnow", obs(0x01)) + require.ErrorContains(t, err, "expired") + + seedRead(t, f, "0xlive", 101) + _, err = f.k.VoteReadResult(f.ctx, v[0], "0xlive", obs(0x01)) + require.NoError(t, err) +} + +func TestVoteReadResult_RejectsNilResult(t *testing.T) { + f := SetupTest(t) + v := seedVoters(t, f, 4) + seedRead(t, f, "0xaa", 500) + + _, err := f.k.VoteReadResult(f.ctx, v[0], "0xaa", nil) + require.Error(t, err) +} + +// A failure inside voting must leave no trace — the request stays exactly as it was. +func TestVoteReadResult_FailureIsAtomic(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(10) + v := seedVoters(t, f, 4) + seedRead(t, f, "0xaa", 500) + + f.uvalidator.voteErr = errTest + _, err := f.k.VoteReadResult(f.ctx, v[0], "0xaa", obs(0x01)) + require.Error(t, err) + + ur, found := f.k.GetUniversalRead(f.ctx, "0xaa") + require.True(t, found) + require.Equal(t, types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING, ur.Status, + "a failed vote must not advance the request") + require.Empty(t, ur.BallotKey) +} + +func TestVoteReadResult_RejectsWhenNoVoters(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(10) + seedRead(t, f, "0xaa", 500) + + _, err := f.k.VoteReadResult(f.ctx, sdk.ValAddress("nobody"), "0xaa", obs(0x01)) + require.ErrorContains(t, err, "no eligible") +} + +// The ballot the record points at is the one the terminal hook will resolve back. +func TestVoteReadResult_BallotResolvesBackToRequest(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(10) + v := seedVoters(t, f, 4) + seedRead(t, f, "0xaa", 500) + + _, err := f.k.VoteReadResult(f.ctx, v[0], "0xaa", obs(0x01)) + require.NoError(t, err) + + ur, _ := f.k.GetUniversalRead(f.ctx, "0xaa") + back, found := f.k.GetUniversalReadByBallot(f.ctx, ur.BallotKey) + require.True(t, found, "the terminal hook must be able to find this request") + require.Equal(t, "0xaa", back.Id) +} + +// The ballot's deadline must be the request's own. x/uvalidator stores expiry as +// created + delta, so the delta handed to VoteOnBallot has to close exactly that +// gap — otherwise the two clocks disagree about when the request is over. +func TestVoteReadResult_BallotInheritsRequestDeadline(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(120) + v := seedVoters(t, f, 4) + seedRead(t, f, "0xaa", 500) + + _, err := f.k.VoteReadResult(f.ctx, v[0], "0xaa", obs(0x01)) + require.NoError(t, err) + + ur, _ := f.k.GetUniversalRead(f.ctx, "0xaa") + delta := f.uvalidator.expiryOf(ur.BallotKey) + require.Equal(t, int64(380), delta, "500 - 120") + require.Equal(t, int64(500), f.ctx.BlockHeight()+delta, + "ballot expires exactly when the request does") +} + +// Requests with different deadlines must not share one expiry. +func TestVoteReadResult_DeadlineIsPerRequest(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(100) + v := seedVoters(t, f, 4) + + seedRead(t, f, "0xsoon", 150) + seedRead(t, f, "0xlate", 9_000) + + _, err := f.k.VoteReadResult(f.ctx, v[0], "0xsoon", obs(0x01)) + require.NoError(t, err) + _, err = f.k.VoteReadResult(f.ctx, v[0], "0xlate", obs(0x01)) + require.NoError(t, err) + + soon, _ := f.k.GetUniversalRead(f.ctx, "0xsoon") + late, _ := f.k.GetUniversalRead(f.ctx, "0xlate") + + require.Equal(t, int64(50), f.uvalidator.expiryOf(soon.BallotKey)) + require.Equal(t, int64(8_900), f.uvalidator.expiryOf(late.BallotKey)) +} + +func TestVoteReadResult_RejectsMissingRequestBody(t *testing.T) { + f := SetupTest(t) + f.ctx = f.ctx.WithBlockHeight(10) + v := seedVoters(t, f, 4) + + require.NoError(t, f.k.SetUniversalRead(f.ctx, types.UniversalRead{ + Id: "0xnobody", + Status: types.UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING, + })) + + _, err := f.k.VoteReadResult(f.ctx, v[0], "0xnobody", obs(0x01)) + require.ErrorContains(t, err, "no request body") +} diff --git a/x/ucallback/module.go b/x/ucallback/module.go new file mode 100755 index 00000000..c613f9ce --- /dev/null +++ b/x/ucallback/module.go @@ -0,0 +1,150 @@ +package module + +import ( + "context" + "encoding/json" + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + + abci "github.com/cometbft/cometbft/abci/types" + + "cosmossdk.io/client/v2/autocli" + errorsmod "cosmossdk.io/errors" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + + "github.com/pushchain/push-chain-node/x/ucallback/keeper" + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +const ( + // ConsensusVersion defines the current x/ucallback module consensus version. + ConsensusVersion = 1 +) + +var ( + _ module.AppModuleBasic = AppModuleBasic{} + _ module.AppModuleGenesis = AppModule{} + _ module.AppModule = AppModule{} + + _ autocli.HasAutoCLIConfig = AppModule{} +) + +// AppModuleBasic defines the basic application module used by the wasm module. +type AppModuleBasic struct { + cdc codec.Codec +} + +type AppModule struct { + AppModuleBasic + + keeper keeper.Keeper +} + +// NewAppModule constructor +func NewAppModule( + cdc codec.Codec, + keeper keeper.Keeper, +) *AppModule { + return &AppModule{ + AppModuleBasic: AppModuleBasic{cdc: cdc}, + keeper: keeper, + } +} + +func (a AppModuleBasic) Name() string { + return types.ModuleName +} + +func (a AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(&types.GenesisState{ + Params: types.DefaultParams(), + }) +} + +func (a AppModuleBasic) ValidateGenesis(marshaler codec.JSONCodec, _ client.TxEncodingConfig, message json.RawMessage) error { + var data types.GenesisState + err := marshaler.UnmarshalJSON(message, &data) + if err != nil { + return err + } + if err := data.Params.Validate(); err != nil { + return errorsmod.Wrap(err, "params") + } + return nil +} + +func (a AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) { +} + +func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) + if err != nil { + // same behavior as in cosmos-sdk + panic(err) + } +} + +// Disable in favor of autocli.go. If you wish to use these, it will override AutoCLI methods. +/* +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.NewTxCmd() +} + +func (a AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} +*/ + +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterLegacyAminoCodec(cdc) +} + +func (a AppModuleBasic) RegisterInterfaces(r codectypes.InterfaceRegistry) { + types.RegisterInterfaces(r) +} + +func (a AppModule) InitGenesis(ctx sdk.Context, marshaler codec.JSONCodec, message json.RawMessage) []abci.ValidatorUpdate { + var genesisState types.GenesisState + marshaler.MustUnmarshalJSON(message, &genesisState) + + if err := a.keeper.Params.Set(ctx, genesisState.Params); err != nil { + panic(err) + } + + if err := a.keeper.InitGenesis(ctx, &genesisState); err != nil { + panic(err) + } + + return nil +} + +func (a AppModule) ExportGenesis(ctx sdk.Context, marshaler codec.JSONCodec) json.RawMessage { + genState := a.keeper.ExportGenesis(ctx) + return marshaler.MustMarshalJSON(genState) +} + +func (a AppModule) RegisterInvariants(_ sdk.InvariantRegistry) { +} + +func (a AppModule) QuerierRoute() string { + return types.QuerierRoute +} + +func (a AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(a.keeper)) + types.RegisterQueryServer(cfg.QueryServer(), keeper.NewQuerier(a.keeper)) +} + +// ConsensusVersion is a sequence number for state-breaking change of the +// module. It should be incremented on each consensus-breaking change +// introduced by the module. To avoid wrong/empty versions, the initial version +// should be set to 1. +func (a AppModule) ConsensusVersion() uint64 { + return ConsensusVersion +} diff --git a/x/ucallback/types/ballot.go b/x/ucallback/types/ballot.go new file mode 100644 index 00000000..f9adb790 --- /dev/null +++ b/x/ucallback/types/ballot.go @@ -0,0 +1,110 @@ +package types + +import ( + "crypto/sha256" + "encoding/hex" + "fmt" + "strings" + + "cosmossdk.io/collections" +) + +// ReadBallotDomain separates read-result ballot keys from every other ballot +// namespace on the chain, so a digest collision across modules is not possible. +var ReadBallotDomain = collections.NewPrefix(1) + +// VotesThresholdNumerator / VotesThresholdDenominator give the >2/3 quorum used +// chain-wide. Mirrors x/uexecutor's constants so read ballots finalize on the same +// threshold as inbound and outbound ones. +const ( + VotesThresholdNumerator = 2 + VotesThresholdDenominator = 3 +) + +// BallotExpiryAfterBlocks converts a read request's absolute deadline into the +// relative argument VoteOnBallot expects. +// +// x/uvalidator stores BlockHeightExpiry as createdHeight + expiryAfterBlocks +// (types/ballot.go:109), so an absolute target has to be expressed as a delta from +// the height the ballot is created at. +// +// The two clocks are deliberately fused: the ballot expires exactly when the +// request does. x/uexecutor instead passes an inert 100M-block expiry to keep +// ballots alive indefinitely, but a read has a real deadline of its own — set by +// the app, enforced by the contract at UniversalCallback.sol:207 — and a ballot +// that outlived it could only ever finalize into a request no longer worth +// fulfilling. +// +// Returns at least 1 so a ballot is never created already expired. Callers reject +// past-deadline requests before reaching here; this is the backstop. +func BallotExpiryAfterBlocks(expiryHeight uint64, currentHeight int64) int64 { + delta := int64(expiryHeight) - currentHeight + if delta < 1 { + return 1 + } + return delta +} + +// GetReadBallotKey derives the ballot a (requestId, observation) pair votes on. +// +// The ballot model is binary: validators vote SUCCESS or FAILURE on a key that +// already encodes the observation. Agreement is therefore expressed by arriving at +// the same key — two validators reporting different result data produce different +// ballots, and neither reaches quorum until enough validators agree. +// +// Two consequences follow, and both are load-bearing: +// +// 1. Every field that callers must agree on has to be in this digest. Omitting one +// would let validators finalize a ballot while disagreeing about it. +// +// 2. Nothing validator-local may be in it. This is why ReadResult carries no error +// message: free-text error strings differ per validator, so including one would +// scatter honest validators across distinct ballots and quorum would never form. +// x/uexecutor's outbound key does hash an ErrorMsg (keys.go:158) — we deliberately +// do not follow it there. +// +// Aggregates are excluded, see readResultFields. +func GetReadBallotKey(requestID string, result *ReadResult) (string, error) { + if requestID == "" { + return "", fmt.Errorf("cannot derive ballot key: empty request id") + } + if result == nil { + return "", fmt.Errorf("cannot derive ballot key: nil result") + } + + parts := append([]string{strings.ToLower(requestID)}, readResultFields(result)...) + return hashFields(ReadBallotDomain, parts...), nil +} + +// readResultFields renders the consensus-relevant part of an observation. +// +// `aggregates` is deliberately absent. It is reserved for v2 MEDIAN mode, where +// validators submit differing per-field values that are reduced afterwards — the +// opposite of the identical-observation model this key assumes. Hashing it now +// would be harmless (it is always empty in v1) but would silently become +// consensus-breaking the moment v2 populates it: the same read would map to a +// different ballot before and after the upgrade. Excluding it from the start keeps +// v2 a purely additive change. +func readResultFields(r *ReadResult) []string { + return []string{ + fmt.Sprintf("%d", int32(r.Status)), + hex.EncodeToString(r.ResultData), + fmt.Sprintf("%d", r.ObservedBlockHeight), + hex.EncodeToString(r.ObservedBlockHash), + } +} + +// hashFields builds a domain-separated digest over pre-hashed parts, so a value +// containing the ":" join character cannot be made to impersonate a field boundary. +// Same construction as x/uexecutor/types/keys.go:83. +func hashFields(domain collections.Prefix, parts ...string) string { + hashed := make([]string, 0, len(parts)+1) + d := sha256.Sum256(domain.Bytes()) + hashed = append(hashed, hex.EncodeToString(d[:])) + for _, p := range parts { + sum := sha256.Sum256([]byte(p)) + hashed = append(hashed, hex.EncodeToString(sum[:])) + } + final := sha256.Sum256([]byte(strings.Join(hashed, ":"))) + return hex.EncodeToString(final[:]) +} diff --git a/x/ucallback/types/ballot_test.go b/x/ucallback/types/ballot_test.go new file mode 100644 index 00000000..91efa879 --- /dev/null +++ b/x/ucallback/types/ballot_test.go @@ -0,0 +1,128 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +func result() *types.ReadResult { + return &types.ReadResult{ + Status: types.ReadStatus_READ_STATUS_SUCCESS, + ResultData: []byte{0xde, 0xad}, + ObservedBlockHeight: 8_000_000, + ObservedBlockHash: []byte{0xbe, 0xef}, + } +} + +func keyOf(t *testing.T, id string, r *types.ReadResult) string { + t.Helper() + k, err := types.GetReadBallotKey(id, r) + require.NoError(t, err) + return k +} + +// Identical observations must converge, or quorum can never form. +func TestGetReadBallotKey_IdenticalObservationsAgree(t *testing.T) { + require.Equal(t, keyOf(t, "0xaa", result()), keyOf(t, "0xaa", result())) +} + +// Every consensus-relevant field must move the key. If one did not, validators +// could finalize a ballot while disagreeing about that field. +func TestGetReadBallotKey_EveryFieldIsBinding(t *testing.T) { + base := keyOf(t, "0xaa", result()) + + for name, mutate := range map[string]func(*types.ReadResult){ + "status": func(r *types.ReadResult) { r.Status = types.ReadStatus_READ_STATUS_ERROR }, + "result_data": func(r *types.ReadResult) { r.ResultData = []byte{0x01} }, + "block_height": func(r *types.ReadResult) { r.ObservedBlockHeight = 8_000_001 }, + "block_hash": func(r *types.ReadResult) { r.ObservedBlockHash = []byte{0x02} }, + } { + t.Run(name, func(t *testing.T) { + r := result() + mutate(r) + require.NotEqual(t, base, keyOf(t, "0xaa", r), + "%s must change the ballot key", name) + }) + } + + // and the request id itself + require.NotEqual(t, base, keyOf(t, "0xbb", result())) +} + +// Aggregates are reserved for v2 MEDIAN and must NOT participate. Hashing them now +// would make the v2 rollout consensus-breaking: the same read would map to a +// different ballot before and after aggregates start being populated. +func TestGetReadBallotKey_ExcludesAggregates(t *testing.T) { + withAgg := result() + withAgg.Aggregates = []*types.AggregateValue{ + {ExtractIndex: 0, Mode: 1, Value: []byte{0x09}}, + } + + require.Equal(t, keyOf(t, "0xaa", result()), keyOf(t, "0xaa", withAgg), + "aggregates must not affect the ballot key") +} + +// Field boundaries must not be forgeable by embedding the join character. +func TestGetReadBallotKey_FieldsCannotBleed(t *testing.T) { + a := result() + a.ResultData = []byte("A:B") + b := result() + b.ResultData = []byte("A") + b.ObservedBlockHash = []byte("B") + + require.NotEqual(t, keyOf(t, "0xaa", a), keyOf(t, "0xaa", b)) +} + +// Request ids differing only in case are the same request. +func TestGetReadBallotKey_RequestIDCaseInsensitive(t *testing.T) { + require.Equal(t, keyOf(t, "0xAABB", result()), keyOf(t, "0xaabb", result())) +} + +func TestGetReadBallotKey_Rejects(t *testing.T) { + _, err := types.GetReadBallotKey("", result()) + require.Error(t, err) + + _, err = types.GetReadBallotKey("0xaa", nil) + require.Error(t, err) +} + +// The ballot's deadline must land exactly on the request's, since x/uvalidator +// stores expiry as created + delta while the request carries an absolute height. +func TestBallotExpiryAfterBlocks_LandsOnRequestDeadline(t *testing.T) { + for _, tc := range []struct { + name string + expiry uint64 + current int64 + want int64 + }{ + {"future deadline", 500, 100, 400}, + {"next block", 101, 100, 1}, + {"from genesis", 900_000, 0, 900_000}, + } { + t.Run(tc.name, func(t *testing.T) { + got := types.BallotExpiryAfterBlocks(tc.expiry, tc.current) + require.Equal(t, tc.want, got) + require.Equal(t, int64(tc.expiry), tc.current+got, + "created + delta must equal the request's own deadline") + }) + } +} + +// A ballot must never be born already expired, even if the caller slipped a +// past-deadline request through. +func TestBallotExpiryAfterBlocks_NeverBornExpired(t *testing.T) { + for _, tc := range []struct { + expiry uint64 + current int64 + }{ + {100, 100}, // exactly at the deadline + {50, 100}, // past it + {0, 100}, // unset + } { + require.Equal(t, int64(1), types.BallotExpiryAfterBlocks(tc.expiry, tc.current), + "expiry=%d current=%d", tc.expiry, tc.current) + } +} diff --git a/x/ucallback/types/codec.go b/x/ucallback/types/codec.go new file mode 100755 index 00000000..6d57a9e3 --- /dev/null +++ b/x/ucallback/types/codec.go @@ -0,0 +1,35 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +var ( + amino = codec.NewLegacyAmino() + AminoCdc = codec.NewAminoCodec(amino) +) + +func init() { + RegisterLegacyAminoCodec(amino) + cryptocodec.RegisterCrypto(amino) + sdk.RegisterLegacyAminoCodec(amino) +} + +// RegisterLegacyAminoCodec registers concrete types on the LegacyAmino codec +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(&MsgUpdateParams{}, ModuleName+"/MsgUpdateParams", nil) +} + +func RegisterInterfaces(registry types.InterfaceRegistry) { + + registry.RegisterImplementations( + (*sdk.Msg)(nil), + &MsgUpdateParams{}, + ) + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} diff --git a/x/ucallback/types/expected_keepers.go b/x/ucallback/types/expected_keepers.go new file mode 100644 index 00000000..3c6e8058 --- /dev/null +++ b/x/ucallback/types/expected_keepers.go @@ -0,0 +1,30 @@ +package types + +import ( + "context" + + uvalidatortypes "github.com/pushchain/push-chain-node/x/uvalidator/types" +) + +// UValidatorKeeper is the slice of x/uvalidator that x/ucallback needs to run a +// read-result ballot. Narrower than x/uexecutor's equivalent — read voting needs +// the voter set, the ballot primitive, and the two eligibility checks, nothing more. +type UValidatorKeeper interface { + IsBondedUniversalValidator(ctx context.Context, universalValidator string) (bool, error) + IsTombstonedUniversalValidator(ctx context.Context, universalValidator string) (bool, error) + GetEligibleVoters(ctx context.Context) ([]uvalidatortypes.UniversalValidator, error) + VoteOnBallot( + ctx context.Context, + id string, + ballotType uvalidatortypes.BallotObservationType, + voter string, + voteResult uvalidatortypes.VoteResult, + voters []string, + votesNeeded int64, + expiryAfterBlocks int64, + ) ( + ballot uvalidatortypes.Ballot, + isFinalized bool, + isNew bool, + err error) +} diff --git a/x/ucallback/types/genesis.go b/x/ucallback/types/genesis.go new file mode 100755 index 00000000..97cad761 --- /dev/null +++ b/x/ucallback/types/genesis.go @@ -0,0 +1,19 @@ +package types + +// DefaultIndex is the default global index +const DefaultIndex uint64 = 1 + +// DefaultGenesis returns the default genesis state +func DefaultGenesis() *GenesisState { + return &GenesisState{ + + Params: DefaultParams(), + } +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (gs GenesisState) Validate() error { + + return gs.Params.Validate() +} diff --git a/x/ucallback/types/genesis.pb.go b/x/ucallback/types/genesis.pb.go new file mode 100644 index 00000000..af640b34 --- /dev/null +++ b/x/ucallback/types/genesis.pb.go @@ -0,0 +1,808 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ucallback/v1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GenesisState defines the module genesis state +type GenesisState struct { + // Params defines all the parameters of the module. + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // universal_reads are key-value pairs from the UniversalReads map. + // + // Only the canonical records are exported. PendingByExpiry and ReadsByTxHash + // are indexes derived from these, and are rebuilt during InitGenesis rather + // than exported — so they cannot be imported out of sync with the records they + // point at. + UniversalReads []UniversalReadEntry `protobuf:"bytes,2,rep,name=universal_reads,json=universalReads,proto3" json:"universal_reads"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_13c1287495624272, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func (m *GenesisState) GetUniversalReads() []UniversalReadEntry { + if m != nil { + return m.UniversalReads + } + return nil +} + +// UniversalReadEntry is one key-value pair from the UniversalReads map. +type UniversalReadEntry struct { + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value UniversalRead `protobuf:"bytes,2,opt,name=value,proto3" json:"value"` +} + +func (m *UniversalReadEntry) Reset() { *m = UniversalReadEntry{} } +func (m *UniversalReadEntry) String() string { return proto.CompactTextString(m) } +func (*UniversalReadEntry) ProtoMessage() {} +func (*UniversalReadEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_13c1287495624272, []int{1} +} +func (m *UniversalReadEntry) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UniversalReadEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UniversalReadEntry.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UniversalReadEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_UniversalReadEntry.Merge(m, src) +} +func (m *UniversalReadEntry) XXX_Size() int { + return m.Size() +} +func (m *UniversalReadEntry) XXX_DiscardUnknown() { + xxx_messageInfo_UniversalReadEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_UniversalReadEntry proto.InternalMessageInfo + +func (m *UniversalReadEntry) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +func (m *UniversalReadEntry) GetValue() UniversalRead { + if m != nil { + return m.Value + } + return UniversalRead{} +} + +// Params defines the set of module parameters. +type Params struct { + SomeValue bool `protobuf:"varint,2,opt,name=some_value,json=someValue,proto3" json:"some_value,omitempty"` +} + +func (m *Params) Reset() { *m = Params{} } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_13c1287495624272, []int{2} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func (m *Params) GetSomeValue() bool { + if m != nil { + return m.SomeValue + } + return false +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "ucallback.v1.GenesisState") + proto.RegisterType((*UniversalReadEntry)(nil), "ucallback.v1.UniversalReadEntry") + proto.RegisterType((*Params)(nil), "ucallback.v1.Params") +} + +func init() { proto.RegisterFile("ucallback/v1/genesis.proto", fileDescriptor_13c1287495624272) } + +var fileDescriptor_13c1287495624272 = []byte{ + // 346 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2a, 0x4d, 0x4e, 0xcc, + 0xc9, 0x49, 0x4a, 0x4c, 0xce, 0xd6, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, + 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x81, 0xcb, 0xe9, 0x95, 0x19, 0x4a, 0x89, 0xa4, + 0xe7, 0xa7, 0xe7, 0x83, 0x25, 0xf4, 0x41, 0x2c, 0x88, 0x1a, 0x29, 0xc1, 0xc4, 0xdc, 0xcc, 0xbc, + 0x7c, 0x7d, 0x30, 0x09, 0x15, 0x92, 0x40, 0x31, 0xb2, 0xa4, 0xb2, 0x20, 0x15, 0x6a, 0xa0, 0xd2, + 0x64, 0x46, 0x2e, 0x1e, 0x77, 0x88, 0x15, 0xc1, 0x25, 0x89, 0x25, 0xa9, 0x42, 0x46, 0x5c, 0x6c, + 0x05, 0x89, 0x45, 0x89, 0xb9, 0xc5, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xdc, 0x46, 0x22, 0x7a, 0xc8, + 0x56, 0xea, 0x05, 0x80, 0xe5, 0x9c, 0x58, 0x4e, 0xdc, 0x93, 0x67, 0x08, 0x82, 0xaa, 0x14, 0xf2, + 0xe7, 0xe2, 0x2f, 0xcd, 0xcb, 0x2c, 0x4b, 0x2d, 0x2a, 0x4e, 0xcc, 0x89, 0x2f, 0x4a, 0x4d, 0x4c, + 0x29, 0x96, 0x60, 0x52, 0x60, 0xd6, 0xe0, 0x36, 0x52, 0x40, 0xd5, 0x1c, 0x0a, 0x53, 0x14, 0x94, + 0x9a, 0x98, 0xe2, 0x9a, 0x57, 0x52, 0x54, 0x09, 0x35, 0x88, 0xaf, 0x14, 0x59, 0xa6, 0x58, 0x29, + 0x9e, 0x4b, 0x08, 0x53, 0xad, 0x90, 0x00, 0x17, 0x73, 0x76, 0x6a, 0x25, 0xd8, 0x5d, 0x9c, 0x41, + 0x20, 0xa6, 0x90, 0x39, 0x17, 0x6b, 0x59, 0x62, 0x4e, 0x69, 0xaa, 0x04, 0x13, 0xd8, 0xad, 0xd2, + 0x78, 0xac, 0x83, 0xda, 0x04, 0x51, 0xaf, 0xe4, 0xc6, 0xc5, 0x06, 0xf1, 0x89, 0x90, 0x2c, 0x17, + 0x57, 0x71, 0x7e, 0x6e, 0x6a, 0x3c, 0xc2, 0x1c, 0x8e, 0x20, 0x4e, 0x90, 0x48, 0x18, 0x48, 0xc0, + 0x4a, 0x76, 0xc6, 0x02, 0x79, 0x86, 0x17, 0x0b, 0xe4, 0x19, 0xbb, 0x9e, 0x6f, 0xd0, 0x12, 0x40, + 0x04, 0x23, 0xc4, 0xe7, 0x4e, 0x01, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, + 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, + 0x65, 0x96, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x5f, 0x50, 0x5a, 0x9c, + 0x91, 0x9c, 0x91, 0x98, 0x99, 0x07, 0x66, 0xe9, 0x82, 0x99, 0xba, 0x79, 0xf9, 0x29, 0xa9, 0xfa, + 0x15, 0xfa, 0x08, 0x23, 0xc1, 0xd1, 0x92, 0xc4, 0x06, 0x8e, 0x17, 0x63, 0x40, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x39, 0x04, 0xe2, 0xe1, 0x06, 0x02, 0x00, 0x00, +} + +func (this *Params) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Params) + if !ok { + that2, ok := that.(Params) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.SomeValue != that1.SomeValue { + return false + } + return true +} +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.UniversalReads) > 0 { + for iNdEx := len(m.UniversalReads) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.UniversalReads[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *UniversalReadEntry) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UniversalReadEntry) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UniversalReadEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Value.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Key) > 0 { + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Key))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Params) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.SomeValue { + i-- + if m.SomeValue { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + if len(m.UniversalReads) > 0 { + for _, e := range m.UniversalReads { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *UniversalReadEntry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Key) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = m.Value.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SomeValue { + n += 2 + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UniversalReads", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UniversalReads = append(m.UniversalReads, UniversalReadEntry{}) + if err := m.UniversalReads[len(m.UniversalReads)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UniversalReadEntry) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UniversalReadEntry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UniversalReadEntry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Value.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Params) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SomeValue", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SomeValue = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/ucallback/types/genesis_test.go b/x/ucallback/types/genesis_test.go new file mode 100755 index 00000000..4b2c37e4 --- /dev/null +++ b/x/ucallback/types/genesis_test.go @@ -0,0 +1,38 @@ +package types_test + +import ( + "testing" + + "github.com/pushchain/push-chain-node/x/ucallback/types" + + "github.com/stretchr/testify/require" +) + +func TestGenesisState_Validate(t *testing.T) { + tests := []struct { + desc string + genState *types.GenesisState + valid bool + }{ + { + desc: "default is valid", + genState: types.DefaultGenesis(), + valid: true, + }, + { + desc: "valid genesis state", + genState: &types.GenesisState{}, + valid: true, + }, + } + for _, tc := range tests { + t.Run(tc.desc, func(t *testing.T) { + err := tc.genState.Validate() + if tc.valid { + require.NoError(t, err) + } else { + require.Error(t, err) + } + }) + } +} diff --git a/x/ucallback/types/keys.go b/x/ucallback/types/keys.go new file mode 100755 index 00000000..fc23ba7c --- /dev/null +++ b/x/ucallback/types/keys.go @@ -0,0 +1,33 @@ +package types + +import ( + "cosmossdk.io/collections" +) + +var ( + // ParamsKey saves the current module params. + ParamsKey = collections.NewPrefix(0) + + // UniversalReadsKey is the canonical record for every read request, + // keyed by requestId. Everything else in this module is an index over it. + UniversalReadsKey = collections.NewPrefix(1) + + // PendingByExpiryKey indexes unsettled reads by the Push Chain height they + // expire at. Key is (expiryHeight, requestId). Entries are removed the moment + // a read settles, which makes this the module's set of in-flight work. + PendingByExpiryKey = collections.NewPrefix(2) + + // ReadsByTxHashKey indexes reads by the Push Chain tx that requested them. + // One transaction can emit several ReadRequested logs; each becomes its own + // UniversalRead, and this index is what reassembles the batch. + // Key is (pushTxHash, requestId). + ReadsByTxHashKey = collections.NewPrefix(3) +) + +const ( + ModuleName = "ucallback" + + StoreKey = ModuleName + + QuerierRoute = ModuleName +) diff --git a/x/ucallback/types/msgs.go b/x/ucallback/types/msgs.go new file mode 100755 index 00000000..360797d6 --- /dev/null +++ b/x/ucallback/types/msgs.go @@ -0,0 +1,49 @@ +package types + +import ( + "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var ( + _ sdk.Msg = &MsgUpdateParams{} +) + +// NewMsgUpdateParams creates new instance of MsgUpdateParams +func NewMsgUpdateParams( + sender sdk.Address, + someValue bool, +) *MsgUpdateParams { + return &MsgUpdateParams{ + Authority: sender.String(), + Params: Params{ + SomeValue: someValue, + }, + } +} + +// Route returns the name of the module +func (msg MsgUpdateParams) Route() string { return ModuleName } + +// Type returns the the action +func (msg MsgUpdateParams) Type() string { return "update_params" } + +// GetSignBytes implements the LegacyMsg interface. +func (msg MsgUpdateParams) GetSignBytes() []byte { + return sdk.MustSortJSON(AminoCdc.MustMarshalJSON(&msg)) +} + +// GetSigners returns the expected signers for a MsgUpdateParams message. +func (msg *MsgUpdateParams) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(msg.Authority) + return []sdk.AccAddress{addr} +} + +// ValidateBasic does a sanity check on the provided data. +func (msg *MsgUpdateParams) Validate() error { + if _, err := sdk.AccAddressFromBech32(msg.Authority); err != nil { + return errors.Wrap(err, "invalid authority address") + } + + return msg.Params.Validate() +} diff --git a/x/ucallback/types/params.go b/x/ucallback/types/params.go new file mode 100755 index 00000000..d9be77ae --- /dev/null +++ b/x/ucallback/types/params.go @@ -0,0 +1,29 @@ +package types + +import ( + "encoding/json" +) + +// DefaultParams returns default module parameters. +func DefaultParams() Params { + // TODO: + return Params{ + SomeValue: true, + } +} + +// Stringer method for Params. +func (p Params) String() string { + bz, err := json.Marshal(p) + if err != nil { + panic(err) + } + + return string(bz) +} + +// Validate does the sanity check on the params. +func (p Params) Validate() error { + // TODO: + return nil +} diff --git a/x/ucallback/types/query.pb.go b/x/ucallback/types/query.pb.go new file mode 100644 index 00000000..cd789ad1 --- /dev/null +++ b/x/ucallback/types/query.pb.go @@ -0,0 +1,1799 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ucallback/v1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + query "github.com/cosmos/cosmos-sdk/types/query" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// QueryParamsRequest is the request type for the Query/Params RPC method. +type QueryParamsRequest struct { +} + +func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } +func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryParamsRequest) ProtoMessage() {} +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a64b97cfcca36b9d, []int{0} +} +func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsRequest.Merge(m, src) +} +func (m *QueryParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo + +// QueryParamsResponse is the response type for the Query/Params RPC method. +type QueryParamsResponse struct { + // params defines the parameters of the module. + Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` +} + +func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } +func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryParamsResponse) ProtoMessage() {} +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a64b97cfcca36b9d, []int{1} +} +func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsResponse.Merge(m, src) +} +func (m *QueryParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo + +func (m *QueryParamsResponse) GetParams() *Params { + if m != nil { + return m.Params + } + return nil +} + +type QueryAllPendingReadRequestsRequest struct { + Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryAllPendingReadRequestsRequest) Reset() { *m = QueryAllPendingReadRequestsRequest{} } +func (m *QueryAllPendingReadRequestsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAllPendingReadRequestsRequest) ProtoMessage() {} +func (*QueryAllPendingReadRequestsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a64b97cfcca36b9d, []int{2} +} +func (m *QueryAllPendingReadRequestsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAllPendingReadRequestsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAllPendingReadRequestsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAllPendingReadRequestsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAllPendingReadRequestsRequest.Merge(m, src) +} +func (m *QueryAllPendingReadRequestsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAllPendingReadRequestsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAllPendingReadRequestsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAllPendingReadRequestsRequest proto.InternalMessageInfo + +func (m *QueryAllPendingReadRequestsRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +type QueryAllPendingReadRequestsResponse struct { + // Reads that are unsettled AND not yet past their expiry height. Requests past + // expiry are withheld here even before the sweeper retires them, so validators + // never take on work that can no longer be fulfilled in time. + Reads []UniversalRead `protobuf:"bytes,1,rep,name=reads,proto3" json:"reads"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryAllPendingReadRequestsResponse) Reset() { *m = QueryAllPendingReadRequestsResponse{} } +func (m *QueryAllPendingReadRequestsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAllPendingReadRequestsResponse) ProtoMessage() {} +func (*QueryAllPendingReadRequestsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a64b97cfcca36b9d, []int{3} +} +func (m *QueryAllPendingReadRequestsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAllPendingReadRequestsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAllPendingReadRequestsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAllPendingReadRequestsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAllPendingReadRequestsResponse.Merge(m, src) +} +func (m *QueryAllPendingReadRequestsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAllPendingReadRequestsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAllPendingReadRequestsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAllPendingReadRequestsResponse proto.InternalMessageInfo + +func (m *QueryAllPendingReadRequestsResponse) GetReads() []UniversalRead { + if m != nil { + return m.Reads + } + return nil +} + +func (m *QueryAllPendingReadRequestsResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + +type QueryUniversalReadRequest struct { + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` +} + +func (m *QueryUniversalReadRequest) Reset() { *m = QueryUniversalReadRequest{} } +func (m *QueryUniversalReadRequest) String() string { return proto.CompactTextString(m) } +func (*QueryUniversalReadRequest) ProtoMessage() {} +func (*QueryUniversalReadRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a64b97cfcca36b9d, []int{4} +} +func (m *QueryUniversalReadRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUniversalReadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUniversalReadRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryUniversalReadRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUniversalReadRequest.Merge(m, src) +} +func (m *QueryUniversalReadRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryUniversalReadRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUniversalReadRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUniversalReadRequest proto.InternalMessageInfo + +func (m *QueryUniversalReadRequest) GetRequestId() string { + if m != nil { + return m.RequestId + } + return "" +} + +type QueryUniversalReadResponse struct { + Read UniversalRead `protobuf:"bytes,1,opt,name=read,proto3" json:"read"` +} + +func (m *QueryUniversalReadResponse) Reset() { *m = QueryUniversalReadResponse{} } +func (m *QueryUniversalReadResponse) String() string { return proto.CompactTextString(m) } +func (*QueryUniversalReadResponse) ProtoMessage() {} +func (*QueryUniversalReadResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a64b97cfcca36b9d, []int{5} +} +func (m *QueryUniversalReadResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUniversalReadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUniversalReadResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryUniversalReadResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUniversalReadResponse.Merge(m, src) +} +func (m *QueryUniversalReadResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryUniversalReadResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUniversalReadResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUniversalReadResponse proto.InternalMessageInfo + +func (m *QueryUniversalReadResponse) GetRead() UniversalRead { + if m != nil { + return m.Read + } + return UniversalRead{} +} + +type QueryReadsByTxRequest struct { + TxHash string `protobuf:"bytes,1,opt,name=tx_hash,json=txHash,proto3" json:"tx_hash,omitempty"` +} + +func (m *QueryReadsByTxRequest) Reset() { *m = QueryReadsByTxRequest{} } +func (m *QueryReadsByTxRequest) String() string { return proto.CompactTextString(m) } +func (*QueryReadsByTxRequest) ProtoMessage() {} +func (*QueryReadsByTxRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a64b97cfcca36b9d, []int{6} +} +func (m *QueryReadsByTxRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryReadsByTxRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryReadsByTxRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryReadsByTxRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryReadsByTxRequest.Merge(m, src) +} +func (m *QueryReadsByTxRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryReadsByTxRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryReadsByTxRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryReadsByTxRequest proto.InternalMessageInfo + +func (m *QueryReadsByTxRequest) GetTxHash() string { + if m != nil { + return m.TxHash + } + return "" +} + +type QueryReadsByTxResponse struct { + // Every read the transaction requested, settled or not, in request-id order. + Reads []UniversalRead `protobuf:"bytes,1,rep,name=reads,proto3" json:"reads"` +} + +func (m *QueryReadsByTxResponse) Reset() { *m = QueryReadsByTxResponse{} } +func (m *QueryReadsByTxResponse) String() string { return proto.CompactTextString(m) } +func (*QueryReadsByTxResponse) ProtoMessage() {} +func (*QueryReadsByTxResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a64b97cfcca36b9d, []int{7} +} +func (m *QueryReadsByTxResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryReadsByTxResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryReadsByTxResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryReadsByTxResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryReadsByTxResponse.Merge(m, src) +} +func (m *QueryReadsByTxResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryReadsByTxResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryReadsByTxResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryReadsByTxResponse proto.InternalMessageInfo + +func (m *QueryReadsByTxResponse) GetReads() []UniversalRead { + if m != nil { + return m.Reads + } + return nil +} + +func init() { + proto.RegisterType((*QueryParamsRequest)(nil), "ucallback.v1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "ucallback.v1.QueryParamsResponse") + proto.RegisterType((*QueryAllPendingReadRequestsRequest)(nil), "ucallback.v1.QueryAllPendingReadRequestsRequest") + proto.RegisterType((*QueryAllPendingReadRequestsResponse)(nil), "ucallback.v1.QueryAllPendingReadRequestsResponse") + proto.RegisterType((*QueryUniversalReadRequest)(nil), "ucallback.v1.QueryUniversalReadRequest") + proto.RegisterType((*QueryUniversalReadResponse)(nil), "ucallback.v1.QueryUniversalReadResponse") + proto.RegisterType((*QueryReadsByTxRequest)(nil), "ucallback.v1.QueryReadsByTxRequest") + proto.RegisterType((*QueryReadsByTxResponse)(nil), "ucallback.v1.QueryReadsByTxResponse") +} + +func init() { proto.RegisterFile("ucallback/v1/query.proto", fileDescriptor_a64b97cfcca36b9d) } + +var fileDescriptor_a64b97cfcca36b9d = []byte{ + // 614 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x94, 0x4f, 0x6f, 0xd3, 0x30, + 0x18, 0xc6, 0x9b, 0xd1, 0x15, 0xd5, 0x83, 0x8b, 0x29, 0x65, 0x84, 0x11, 0x46, 0x0a, 0xac, 0x1a, + 0x5b, 0xbc, 0x16, 0x01, 0x12, 0x37, 0x8a, 0xc4, 0x9f, 0x5b, 0x57, 0xe0, 0xc2, 0x25, 0x72, 0x1a, + 0x2b, 0x89, 0x96, 0xc6, 0x59, 0x9c, 0x54, 0xad, 0xa6, 0x5d, 0xe0, 0x0b, 0x20, 0x21, 0xf1, 0x15, + 0x90, 0xf8, 0x14, 0x1c, 0x77, 0x9c, 0xc4, 0x85, 0x13, 0x42, 0x2d, 0x1f, 0x04, 0xc5, 0x71, 0xb6, + 0xba, 0x44, 0x1d, 0x68, 0x37, 0xcb, 0x7e, 0xde, 0xf7, 0xfd, 0x3d, 0xaf, 0x9e, 0x04, 0xac, 0x26, + 0x7d, 0xec, 0xfb, 0x16, 0xee, 0xef, 0xa1, 0x61, 0x0b, 0xed, 0x27, 0x24, 0x1a, 0x1b, 0x61, 0x44, + 0x63, 0x0a, 0x2f, 0x9d, 0xbc, 0x18, 0xc3, 0x96, 0x5a, 0x73, 0xa8, 0x43, 0xf9, 0x03, 0x4a, 0x4f, + 0x99, 0x46, 0x5d, 0x73, 0x28, 0x75, 0x7c, 0x82, 0x70, 0xe8, 0x21, 0x1c, 0x04, 0x34, 0xc6, 0xb1, + 0x47, 0x03, 0x26, 0x5e, 0x37, 0xfb, 0x94, 0x0d, 0x28, 0x43, 0x16, 0x66, 0x24, 0x6b, 0x8d, 0x86, + 0x2d, 0x8b, 0xc4, 0xb8, 0x85, 0x42, 0xec, 0x78, 0x01, 0x17, 0x0b, 0xad, 0x2a, 0x71, 0x38, 0x24, + 0x20, 0xcc, 0xcb, 0xfb, 0xc8, 0x8c, 0xf1, 0x38, 0x24, 0xe2, 0x45, 0xaf, 0x01, 0xb8, 0x9b, 0xf6, + 0xed, 0xe2, 0x08, 0x0f, 0x58, 0x8f, 0xec, 0x27, 0x84, 0xc5, 0xfa, 0x33, 0x70, 0x45, 0xba, 0x65, + 0x21, 0x0d, 0x18, 0x81, 0x5b, 0xa0, 0x12, 0xf2, 0x9b, 0x55, 0x65, 0x5d, 0x69, 0xae, 0xb4, 0x6b, + 0xc6, 0xac, 0x43, 0x43, 0xa8, 0x85, 0x46, 0xf7, 0x81, 0xce, 0x9b, 0x3c, 0xf5, 0xfd, 0x2e, 0x09, + 0x6c, 0x2f, 0x70, 0x7a, 0x04, 0xdb, 0x62, 0x44, 0x3e, 0x0a, 0x3e, 0x07, 0xe0, 0xd4, 0x8a, 0xe8, + 0x7b, 0xcf, 0xc8, 0x7c, 0x1b, 0xa9, 0x6f, 0x23, 0x5b, 0xa9, 0xf0, 0x6d, 0x74, 0xb1, 0x43, 0x44, + 0x6d, 0x6f, 0xa6, 0x52, 0xff, 0xa2, 0x80, 0xc6, 0xc2, 0x71, 0xc2, 0xc3, 0x63, 0xb0, 0x1c, 0x11, + 0x6c, 0xa7, 0x16, 0x2e, 0x34, 0x57, 0xda, 0x37, 0x64, 0x0b, 0x6f, 0x03, 0x6f, 0x48, 0x22, 0x86, + 0xfd, 0xb4, 0xb6, 0x53, 0x3e, 0xfa, 0x79, 0xab, 0xd4, 0xcb, 0xf4, 0xf0, 0x85, 0x04, 0xba, 0xc4, + 0x41, 0x37, 0xce, 0x04, 0xcd, 0xa6, 0x4a, 0xa4, 0x4f, 0xc0, 0x75, 0x0e, 0x2a, 0xcd, 0xca, 0xd7, + 0x71, 0x13, 0x80, 0x28, 0x3b, 0x9a, 0x9e, 0xcd, 0xd7, 0x51, 0xed, 0x55, 0xc5, 0xcd, 0x2b, 0x5b, + 0x7f, 0x0d, 0xd4, 0xa2, 0x5a, 0xe1, 0xed, 0x21, 0x28, 0xa7, 0xac, 0x62, 0x8b, 0xff, 0x60, 0x8d, + 0xcb, 0xf5, 0x1d, 0x70, 0x95, 0x37, 0x4d, 0x1f, 0x58, 0x67, 0xfc, 0x66, 0x94, 0xc3, 0x5c, 0x03, + 0x17, 0xe3, 0x91, 0xe9, 0x62, 0xe6, 0x0a, 0x92, 0x4a, 0x3c, 0x7a, 0x89, 0x99, 0xab, 0xef, 0x82, + 0xfa, 0x7c, 0xc5, 0x39, 0xd7, 0xdb, 0xfe, 0x56, 0x06, 0xcb, 0xbc, 0x27, 0xdc, 0x03, 0x95, 0x2c, + 0x49, 0x70, 0x5d, 0xae, 0xfe, 0x3b, 0xa8, 0xea, 0xed, 0x05, 0x8a, 0x8c, 0x48, 0x5f, 0x7b, 0xff, + 0xfd, 0xf7, 0xa7, 0xa5, 0x3a, 0xac, 0x21, 0xe9, 0x23, 0xc8, 0x42, 0x0a, 0xbf, 0x2a, 0xa0, 0x5e, + 0x9c, 0x18, 0xb8, 0x53, 0xd0, 0x7b, 0x61, 0x96, 0xd5, 0xd6, 0x7f, 0x54, 0x08, 0xba, 0xfb, 0x9c, + 0xee, 0x2e, 0x6c, 0xcc, 0xd1, 0x65, 0x25, 0x66, 0xba, 0x1b, 0x33, 0xca, 0x89, 0x3e, 0x2b, 0xe0, + 0xb2, 0xb4, 0x42, 0xb8, 0x51, 0x30, 0xb1, 0x28, 0x57, 0x6a, 0xf3, 0x6c, 0xa1, 0x20, 0x6a, 0x73, + 0xa2, 0x2d, 0xb8, 0x29, 0x13, 0x25, 0xb9, 0x98, 0x33, 0x31, 0x74, 0x70, 0x1a, 0xd3, 0x43, 0xf8, + 0x41, 0x01, 0xd5, 0x93, 0x2c, 0xc0, 0x46, 0xc1, 0xac, 0xf9, 0x6c, 0xa9, 0x77, 0x16, 0x8b, 0x16, + 0xaf, 0x87, 0x23, 0x98, 0xd6, 0xd8, 0x8c, 0x47, 0xe8, 0x40, 0x44, 0xf4, 0xb0, 0xd3, 0x3d, 0x9a, + 0x68, 0xca, 0xf1, 0x44, 0x53, 0x7e, 0x4d, 0x34, 0xe5, 0xe3, 0x54, 0x2b, 0x1d, 0x4f, 0xb5, 0xd2, + 0x8f, 0xa9, 0x56, 0x7a, 0xf7, 0xc8, 0xf1, 0x62, 0x37, 0xb1, 0x8c, 0x3e, 0x1d, 0xa0, 0x30, 0x61, + 0x6e, 0xdf, 0xc5, 0x5e, 0xc0, 0x4f, 0xdb, 0xfc, 0xb8, 0x1d, 0x50, 0x9b, 0xa0, 0xd1, 0xcc, 0x10, + 0xfe, 0x8f, 0xb4, 0x2a, 0xfc, 0x27, 0xf9, 0xe0, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x02, 0x65, + 0x30, 0x7f, 0xe4, 0x05, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // Params queries all parameters of the module. + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // AllPendingReadRequests lists read requests still awaiting an observation. + // This is the endpoint universal validators poll. + AllPendingReadRequests(ctx context.Context, in *QueryAllPendingReadRequestsRequest, opts ...grpc.CallOption) (*QueryAllPendingReadRequestsResponse, error) + // UniversalRead returns one read by request id, at any point in its lifecycle. + UniversalRead(ctx context.Context, in *QueryUniversalReadRequest, opts ...grpc.CallOption) (*QueryUniversalReadResponse, error) + // ReadsByTxHash returns every read requested by one Push transaction. A single + // transaction can emit several ReadRequested logs; this reassembles that batch. + ReadsByTx(ctx context.Context, in *QueryReadsByTxRequest, opts ...grpc.CallOption) (*QueryReadsByTxResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, "/ucallback.v1.Query/Params", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) AllPendingReadRequests(ctx context.Context, in *QueryAllPendingReadRequestsRequest, opts ...grpc.CallOption) (*QueryAllPendingReadRequestsResponse, error) { + out := new(QueryAllPendingReadRequestsResponse) + err := c.cc.Invoke(ctx, "/ucallback.v1.Query/AllPendingReadRequests", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) UniversalRead(ctx context.Context, in *QueryUniversalReadRequest, opts ...grpc.CallOption) (*QueryUniversalReadResponse, error) { + out := new(QueryUniversalReadResponse) + err := c.cc.Invoke(ctx, "/ucallback.v1.Query/UniversalRead", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) ReadsByTx(ctx context.Context, in *QueryReadsByTxRequest, opts ...grpc.CallOption) (*QueryReadsByTxResponse, error) { + out := new(QueryReadsByTxResponse) + err := c.cc.Invoke(ctx, "/ucallback.v1.Query/ReadsByTx", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // Params queries all parameters of the module. + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // AllPendingReadRequests lists read requests still awaiting an observation. + // This is the endpoint universal validators poll. + AllPendingReadRequests(context.Context, *QueryAllPendingReadRequestsRequest) (*QueryAllPendingReadRequestsResponse, error) + // UniversalRead returns one read by request id, at any point in its lifecycle. + UniversalRead(context.Context, *QueryUniversalReadRequest) (*QueryUniversalReadResponse, error) + // ReadsByTxHash returns every read requested by one Push transaction. A single + // transaction can emit several ReadRequested logs; this reassembles that batch. + ReadsByTx(context.Context, *QueryReadsByTxRequest) (*QueryReadsByTxResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} +func (*UnimplementedQueryServer) AllPendingReadRequests(ctx context.Context, req *QueryAllPendingReadRequestsRequest) (*QueryAllPendingReadRequestsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AllPendingReadRequests not implemented") +} +func (*UnimplementedQueryServer) UniversalRead(ctx context.Context, req *QueryUniversalReadRequest) (*QueryUniversalReadResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UniversalRead not implemented") +} +func (*UnimplementedQueryServer) ReadsByTx(ctx context.Context, req *QueryReadsByTxRequest) (*QueryReadsByTxResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReadsByTx not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ucallback.v1.Query/Params", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_AllPendingReadRequests_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAllPendingReadRequestsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).AllPendingReadRequests(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ucallback.v1.Query/AllPendingReadRequests", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).AllPendingReadRequests(ctx, req.(*QueryAllPendingReadRequestsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_UniversalRead_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryUniversalReadRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).UniversalRead(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ucallback.v1.Query/UniversalRead", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).UniversalRead(ctx, req.(*QueryUniversalReadRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_ReadsByTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryReadsByTxRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ReadsByTx(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ucallback.v1.Query/ReadsByTx", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ReadsByTx(ctx, req.(*QueryReadsByTxRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "ucallback.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + { + MethodName: "AllPendingReadRequests", + Handler: _Query_AllPendingReadRequests_Handler, + }, + { + MethodName: "UniversalRead", + Handler: _Query_UniversalRead_Handler, + }, + { + MethodName: "ReadsByTx", + Handler: _Query_ReadsByTx_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ucallback/v1/query.proto", +} + +func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Params != nil { + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryAllPendingReadRequestsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAllPendingReadRequestsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAllPendingReadRequestsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryAllPendingReadRequestsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAllPendingReadRequestsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAllPendingReadRequestsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Reads) > 0 { + for iNdEx := len(m.Reads) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Reads[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryUniversalReadRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryUniversalReadRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUniversalReadRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.RequestId) > 0 { + i -= len(m.RequestId) + copy(dAtA[i:], m.RequestId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.RequestId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryUniversalReadResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryUniversalReadResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUniversalReadResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Read.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryReadsByTxRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryReadsByTxRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryReadsByTxRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.TxHash) > 0 { + i -= len(m.TxHash) + copy(dAtA[i:], m.TxHash) + i = encodeVarintQuery(dAtA, i, uint64(len(m.TxHash))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryReadsByTxResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryReadsByTxResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryReadsByTxResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Reads) > 0 { + for iNdEx := len(m.Reads) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Reads[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Params != nil { + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryAllPendingReadRequestsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryAllPendingReadRequestsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Reads) > 0 { + for _, e := range m.Reads { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryUniversalReadRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.RequestId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryUniversalReadResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Read.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryReadsByTxRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.TxHash) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryReadsByTxResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Reads) > 0 { + for _, e := range m.Reads { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Params == nil { + m.Params = &Params{} + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAllPendingReadRequestsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAllPendingReadRequestsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAllPendingReadRequestsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAllPendingReadRequestsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAllPendingReadRequestsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAllPendingReadRequestsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reads", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Reads = append(m.Reads, UniversalRead{}) + if err := m.Reads[len(m.Reads)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryUniversalReadRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryUniversalReadRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryUniversalReadRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RequestId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryUniversalReadResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryUniversalReadResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryUniversalReadResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Read", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Read.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryReadsByTxRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryReadsByTxRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryReadsByTxRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TxHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TxHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryReadsByTxResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryReadsByTxResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryReadsByTxResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reads", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Reads = append(m.Reads, UniversalRead{}) + if err := m.Reads[len(m.Reads)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/ucallback/types/query.pb.gw.go b/x/ucallback/types/query.pb.gw.go new file mode 100644 index 00000000..afad9fe3 --- /dev/null +++ b/x/ucallback/types/query.pb.gw.go @@ -0,0 +1,438 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: ucallback/v1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.Params(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_AllPendingReadRequests_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_AllPendingReadRequests_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAllPendingReadRequestsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_AllPendingReadRequests_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.AllPendingReadRequests(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_AllPendingReadRequests_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAllPendingReadRequestsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_AllPendingReadRequests_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.AllPendingReadRequests(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_UniversalRead_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUniversalReadRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["request_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "request_id") + } + + protoReq.RequestId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "request_id", err) + } + + msg, err := client.UniversalRead(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_UniversalRead_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUniversalReadRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["request_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "request_id") + } + + protoReq.RequestId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "request_id", err) + } + + msg, err := server.UniversalRead(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_ReadsByTx_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryReadsByTxRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["tx_hash"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "tx_hash") + } + + protoReq.TxHash, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "tx_hash", err) + } + + msg, err := client.ReadsByTx(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ReadsByTx_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryReadsByTxRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["tx_hash"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "tx_hash") + } + + protoReq.TxHash, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "tx_hash", err) + } + + msg, err := server.ReadsByTx(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AllPendingReadRequests_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_AllPendingReadRequests_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AllPendingReadRequests_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_UniversalRead_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_UniversalRead_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_UniversalRead_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ReadsByTx_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_ReadsByTx_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ReadsByTx_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AllPendingReadRequests_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_AllPendingReadRequests_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AllPendingReadRequests_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_UniversalRead_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_UniversalRead_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_UniversalRead_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ReadsByTx_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_ReadsByTx_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ReadsByTx_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"ucallback", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_AllPendingReadRequests_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"ucallback", "v1", "pending_read_requests"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_UniversalRead_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"ucallback", "v1", "universal_reads", "request_id"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_ReadsByTx_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"ucallback", "v1", "reads_by_tx", "tx_hash"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Query_Params_0 = runtime.ForwardResponseMessage + + forward_Query_AllPendingReadRequests_0 = runtime.ForwardResponseMessage + + forward_Query_UniversalRead_0 = runtime.ForwardResponseMessage + + forward_Query_ReadsByTx_0 = runtime.ForwardResponseMessage +) diff --git a/x/ucallback/types/read_event.go b/x/ucallback/types/read_event.go new file mode 100644 index 00000000..62c826bf --- /dev/null +++ b/x/ucallback/types/read_event.go @@ -0,0 +1,157 @@ +package types + +import ( + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + evmtypes "github.com/cosmos/evm/x/vm/types" +) + +// readRequestedABI is the ABI fragment for UniversalCallback's ReadRequested +// event, transcribed from push-chain-core-contracts: +// +// src/Interfaces/IUniversalCallback.sol — the event +// src/libraries/ReadTypes.sol — ReadSpec +// src/libraries/Types.sol — UniversalAccountId +// +// Held as ABI JSON rather than hand-assembled abi.Type values so that go-ethereum +// derives topic0 for us. A hand-written signature string would be one silent typo +// away from a filter that never matches anything. +const readRequestedABI = `[{ + "type": "event", + "name": "ReadRequested", + "anonymous": false, + "inputs": [ + {"name": "requestId", "type": "uint256", "indexed": true}, + {"name": "readSpec", "type": "tuple", "indexed": false, "components": [ + {"name": "account", "type": "tuple", "components": [ + {"name": "chainNamespace", "type": "string"}, + {"name": "chainId", "type": "string"}, + {"name": "owner", "type": "bytes"} + ]}, + {"name": "query", "type": "bytes"}, + {"name": "minConfirmations", "type": "uint16"}, + {"name": "blockNumber", "type": "uint64"}, + {"name": "expiryPushChainHeight", "type": "uint64"}, + {"name": "maxFee", "type": "uint256"} + ]}, + {"name": "callbackTarget", "type": "address", "indexed": true}, + {"name": "originalFunder", "type": "address", "indexed": true}, + {"name": "feesDeposited", "type": "uint256", "indexed": false} + ] +}]` + +var ( + readRequestedEvent abi.Event + // ReadRequestedEventSig is topic0 for ReadRequested, derived from the ABI above. + ReadRequestedEventSig common.Hash +) + +func init() { + parsed, err := abi.JSON(strings.NewReader(readRequestedABI)) + if err != nil { + panic(fmt.Sprintf("ucallback: bad ReadRequested ABI: %v", err)) + } + ev, ok := parsed.Events["ReadRequested"] + if !ok { + panic("ucallback: ReadRequested missing from parsed ABI") + } + readRequestedEvent = ev + ReadRequestedEventSig = ev.ID +} + +// ReadRequestedEvent is a decoded ReadRequested log. +// +// RequestID keeps the raw 32-byte topic hex rather than a decimal string: it is +// handed straight back to the contract as a uint256 on fulfil/expire, and the hex +// form round-trips without a base conversion in the middle. +type ReadRequestedEvent struct { + RequestID string + CallbackTarget string + OriginalFunder string + + ChainNamespace string + ChainID string + Owner []byte + + Query []byte + MinConfirmations uint16 + BlockNumber uint64 + ExpiryPushChainHeight uint64 + MaxFee *big.Int + + FeesDeposited *big.Int +} + +// DestinationChain returns the CAIP-2 identifier the event's account refers to, +// e.g. "eip155:11155111". The contract emits namespace and id separately; every +// other module keys chains by the joined form. +func (e *ReadRequestedEvent) DestinationChain() string { + return e.ChainNamespace + ":" + e.ChainID +} + +// unpackTarget mirrors the non-indexed argument layout of ReadRequested. Field +// order and types must match the ABI above exactly; go-ethereum maps by position +// within each tuple, not by name. +type unpackTarget struct { + ReadSpec struct { + Account struct { + ChainNamespace string + ChainId string + Owner []byte + } + Query []byte + MinConfirmations uint16 + BlockNumber uint64 + ExpiryPushChainHeight uint64 + MaxFee *big.Int + } + FeesDeposited *big.Int +} + +// DecodeReadRequestedFromLog decodes a ReadRequested log. +// +// The caller is responsible for having checked log.Address — this function only +// validates the topic layout, so on its own it would happily decode a forged event +// from an arbitrary contract. +func DecodeReadRequestedFromLog(log *evmtypes.Log) (*ReadRequestedEvent, error) { + if log == nil { + return nil, fmt.Errorf("nil log") + } + if len(log.Topics) != 4 { + return nil, fmt.Errorf("ReadRequested expects 4 topics, got %d", len(log.Topics)) + } + if !strings.EqualFold(log.Topics[0], ReadRequestedEventSig.Hex()) { + return nil, fmt.Errorf("not a ReadRequested event") + } + + var out unpackTarget + values, err := readRequestedEvent.Inputs.NonIndexed().Unpack(log.Data) + if err != nil { + return nil, fmt.Errorf("failed to unpack ReadRequested: %w", err) + } + if err := readRequestedEvent.Inputs.NonIndexed().Copy(&out, values); err != nil { + return nil, fmt.Errorf("failed to map ReadRequested fields: %w", err) + } + + return &ReadRequestedEvent{ + RequestID: strings.ToLower(log.Topics[1]), + CallbackTarget: common.HexToAddress(log.Topics[2]).Hex(), + OriginalFunder: common.HexToAddress(log.Topics[3]).Hex(), + + ChainNamespace: out.ReadSpec.Account.ChainNamespace, + ChainID: out.ReadSpec.Account.ChainId, + Owner: out.ReadSpec.Account.Owner, + + Query: out.ReadSpec.Query, + MinConfirmations: out.ReadSpec.MinConfirmations, + BlockNumber: out.ReadSpec.BlockNumber, + ExpiryPushChainHeight: out.ReadSpec.ExpiryPushChainHeight, + MaxFee: out.ReadSpec.MaxFee, + + FeesDeposited: out.FeesDeposited, + }, nil +} diff --git a/x/ucallback/types/read_event_test.go b/x/ucallback/types/read_event_test.go new file mode 100644 index 00000000..7f0f8552 --- /dev/null +++ b/x/ucallback/types/read_event_test.go @@ -0,0 +1,174 @@ +package types_test + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + evmtypes "github.com/cosmos/evm/x/vm/types" + + "github.com/pushchain/push-chain-node/x/ucallback/types" +) + +// readSpec mirrors the contract's ReadSpec for encoding test fixtures. +type account struct { + ChainNamespace string + ChainId string + Owner []byte +} + +type readSpec struct { + Account account + Query []byte + MinConfirmations uint16 + BlockNumber uint64 + ExpiryPushChainHeight uint64 + MaxFee *big.Int +} + +func specArgs(t *testing.T) abi.Arguments { + t.Helper() + specType, err := abi.NewType("tuple", "", []abi.ArgumentMarshaling{ + {Name: "account", Type: "tuple", Components: []abi.ArgumentMarshaling{ + {Name: "chainNamespace", Type: "string"}, + {Name: "chainId", Type: "string"}, + {Name: "owner", Type: "bytes"}, + }}, + {Name: "query", Type: "bytes"}, + {Name: "minConfirmations", Type: "uint16"}, + {Name: "blockNumber", Type: "uint64"}, + {Name: "expiryPushChainHeight", Type: "uint64"}, + {Name: "maxFee", Type: "uint256"}, + }) + require.NoError(t, err) + uint256Type, err := abi.NewType("uint256", "", nil) + require.NoError(t, err) + return abi.Arguments{{Type: specType}, {Type: uint256Type}} +} + +func encodeLog(t *testing.T, spec readSpec, fees *big.Int, requestID, target, funder string) *evmtypes.Log { + t.Helper() + data, err := specArgs(t).Pack(spec, fees) + require.NoError(t, err) + + return &evmtypes.Log{ + Address: "0x00000000000000000000000000000000000000C2", + Topics: []string{ + types.ReadRequestedEventSig.Hex(), + requestID, + common.HexToHash(target).Hex(), + common.HexToHash(funder).Hex(), + }, + Data: data, + } +} + +func sampleSpec() readSpec { + return readSpec{ + Account: account{ + ChainNamespace: "eip155", + ChainId: "11155111", + Owner: common.FromHex("0x1111111111111111111111111111111111111111"), + }, + Query: common.FromHex("0xdeadbeef"), + MinConfirmations: 12, + BlockNumber: 8_000_123, + ExpiryPushChainHeight: 900_000, + MaxFee: big.NewInt(5_000_000), + } +} + +// A round-trip through real ABI encoding — if the ABI fragment in read_event.go +// disagrees with the contract's struct layout, this fails. +func TestDecodeReadRequestedFromLog_RoundTrip(t *testing.T) { + spec := sampleSpec() + lg := encodeLog(t, spec, big.NewInt(42_000), + "0x00000000000000000000000000000000000000000000000000000000000000ab", + "0x2222222222222222222222222222222222222222", + "0x3333333333333333333333333333333333333333") + + ev, err := types.DecodeReadRequestedFromLog(lg) + require.NoError(t, err) + + require.Equal(t, "eip155", ev.ChainNamespace) + require.Equal(t, "11155111", ev.ChainID) + require.Equal(t, "eip155:11155111", ev.DestinationChain()) + require.Equal(t, common.FromHex("0x1111111111111111111111111111111111111111"), ev.Owner) + require.Equal(t, common.FromHex("0xdeadbeef"), ev.Query) + require.Equal(t, uint16(12), ev.MinConfirmations) + require.Equal(t, uint64(8_000_123), ev.BlockNumber) + require.Equal(t, uint64(900_000), ev.ExpiryPushChainHeight) + require.Equal(t, big.NewInt(5_000_000), ev.MaxFee) + require.Equal(t, big.NewInt(42_000), ev.FeesDeposited) + + require.Equal(t, "0x2222222222222222222222222222222222222222", ev.CallbackTarget) + require.Equal(t, "0x3333333333333333333333333333333333333333", ev.OriginalFunder) + require.Equal(t, + "0x00000000000000000000000000000000000000000000000000000000000000ab", + ev.RequestID, "request id keeps the full 32-byte topic, lowercased") +} + +// topic0 must be derived, never hand-written: a typo would silently produce a +// filter that matches nothing. +func TestReadRequestedEventSig_IsStable(t *testing.T) { + require.Equal(t, + "0xef9f2bd93134c510809440802fbb5f8056161a88fa47ca5758104364a83d9d8e", + types.ReadRequestedEventSig.Hex(), + "topic0 changed — the contract's event signature moved, or the ABI fragment drifted") +} + +func TestDecodeReadRequestedFromLog_Rejects(t *testing.T) { + spec := sampleSpec() + good := encodeLog(t, spec, big.NewInt(1), + "0x00000000000000000000000000000000000000000000000000000000000000ab", + "0x2222222222222222222222222222222222222222", + "0x3333333333333333333333333333333333333333") + + t.Run("nil log", func(t *testing.T) { + _, err := types.DecodeReadRequestedFromLog(nil) + require.Error(t, err) + }) + + t.Run("wrong topic0", func(t *testing.T) { + bad := *good + bad.Topics = append([]string{}, good.Topics...) + bad.Topics[0] = common.HexToHash("0xdead").Hex() + _, err := types.DecodeReadRequestedFromLog(&bad) + require.Error(t, err) + }) + + t.Run("too few topics", func(t *testing.T) { + bad := *good + bad.Topics = good.Topics[:3] + _, err := types.DecodeReadRequestedFromLog(&bad) + require.Error(t, err) + }) + + t.Run("truncated data", func(t *testing.T) { + bad := *good + bad.Data = good.Data[:len(good.Data)/2] + _, err := types.DecodeReadRequestedFromLog(&bad) + require.Error(t, err) + }) +} + +// Empty owner/query are legitimate on some chains; they must not be an error. +func TestDecodeReadRequestedFromLog_EmptyBytes(t *testing.T) { + spec := sampleSpec() + spec.Account.Owner = []byte{} + spec.Query = []byte{} + spec.MaxFee = big.NewInt(0) + + lg := encodeLog(t, spec, big.NewInt(0), + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x2222222222222222222222222222222222222222", + "0x3333333333333333333333333333333333333333") + + ev, err := types.DecodeReadRequestedFromLog(lg) + require.NoError(t, err) + require.Empty(t, ev.Owner) + require.Empty(t, ev.Query) +} diff --git a/x/ucallback/types/tx.pb.go b/x/ucallback/types/tx.pb.go new file mode 100644 index 00000000..927ada05 --- /dev/null +++ b/x/ucallback/types/tx.pb.go @@ -0,0 +1,1105 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ucallback/v1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// MsgUpdateParams is the Msg/UpdateParams request type. +// +// Since: cosmos-sdk 0.47 +type MsgUpdateParams struct { + // authority is the address of the governance account. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the parameters to update. + // + // NOTE: All parameters must be supplied. + Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` +} + +func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } +func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParams) ProtoMessage() {} +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return fileDescriptor_9cc90e16cf6966ee, []int{0} +} +func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParams.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParams.Merge(m, src) +} +func (m *MsgUpdateParams) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParams) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParams.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParams proto.InternalMessageInfo + +func (m *MsgUpdateParams) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func (m *MsgUpdateParams) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +// MsgUpdateParamsResponse defines the response structure for executing a +// MsgUpdateParams message. +// +// Since: cosmos-sdk 0.47 +type MsgUpdateParamsResponse struct { +} + +func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse{} } +func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParamsResponse) ProtoMessage() {} +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_9cc90e16cf6966ee, []int{1} +} +func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParamsResponse.Merge(m, src) +} +func (m *MsgUpdateParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo + +// MsgVoteReadResult is broadcast by a universal validator that has executed a +// read request against the destination chain. +// +// The ballot the vote lands on is derived from (request_id, result), so two +// validators reporting the same observation converge on one ballot and any +// disagreement produces a distinct ballot that never reaches quorum. Nothing +// validator-local may appear in `result` for that reason — notably there is no +// error message field. +type MsgVoteReadResult struct { + // signer is the Cosmos address of the voting universal validator. + Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` + // request_id identifies the read request being voted on. + RequestId string `protobuf:"bytes,2,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + // result is the observation. Every field participates in the ballot key. + Result *ReadResult `protobuf:"bytes,3,opt,name=result,proto3" json:"result,omitempty"` +} + +func (m *MsgVoteReadResult) Reset() { *m = MsgVoteReadResult{} } +func (m *MsgVoteReadResult) String() string { return proto.CompactTextString(m) } +func (*MsgVoteReadResult) ProtoMessage() {} +func (*MsgVoteReadResult) Descriptor() ([]byte, []int) { + return fileDescriptor_9cc90e16cf6966ee, []int{2} +} +func (m *MsgVoteReadResult) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgVoteReadResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgVoteReadResult.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgVoteReadResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgVoteReadResult.Merge(m, src) +} +func (m *MsgVoteReadResult) XXX_Size() int { + return m.Size() +} +func (m *MsgVoteReadResult) XXX_DiscardUnknown() { + xxx_messageInfo_MsgVoteReadResult.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgVoteReadResult proto.InternalMessageInfo + +func (m *MsgVoteReadResult) GetSigner() string { + if m != nil { + return m.Signer + } + return "" +} + +func (m *MsgVoteReadResult) GetRequestId() string { + if m != nil { + return m.RequestId + } + return "" +} + +func (m *MsgVoteReadResult) GetResult() *ReadResult { + if m != nil { + return m.Result + } + return nil +} + +type MsgVoteReadResultResponse struct { + // finalized reports whether this vote carried the ballot to quorum. + Finalized bool `protobuf:"varint,1,opt,name=finalized,proto3" json:"finalized,omitempty"` +} + +func (m *MsgVoteReadResultResponse) Reset() { *m = MsgVoteReadResultResponse{} } +func (m *MsgVoteReadResultResponse) String() string { return proto.CompactTextString(m) } +func (*MsgVoteReadResultResponse) ProtoMessage() {} +func (*MsgVoteReadResultResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_9cc90e16cf6966ee, []int{3} +} +func (m *MsgVoteReadResultResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgVoteReadResultResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgVoteReadResultResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgVoteReadResultResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgVoteReadResultResponse.Merge(m, src) +} +func (m *MsgVoteReadResultResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgVoteReadResultResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgVoteReadResultResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgVoteReadResultResponse proto.InternalMessageInfo + +func (m *MsgVoteReadResultResponse) GetFinalized() bool { + if m != nil { + return m.Finalized + } + return false +} + +func init() { + proto.RegisterType((*MsgUpdateParams)(nil), "ucallback.v1.MsgUpdateParams") + proto.RegisterType((*MsgUpdateParamsResponse)(nil), "ucallback.v1.MsgUpdateParamsResponse") + proto.RegisterType((*MsgVoteReadResult)(nil), "ucallback.v1.MsgVoteReadResult") + proto.RegisterType((*MsgVoteReadResultResponse)(nil), "ucallback.v1.MsgVoteReadResultResponse") +} + +func init() { proto.RegisterFile("ucallback/v1/tx.proto", fileDescriptor_9cc90e16cf6966ee) } + +var fileDescriptor_9cc90e16cf6966ee = []byte{ + // 480 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x53, 0x3f, 0x6f, 0xd3, 0x40, + 0x1c, 0xcd, 0x51, 0x88, 0xf0, 0x51, 0x15, 0xd5, 0x0a, 0xaa, 0x63, 0xa8, 0x5b, 0x45, 0x42, 0x54, + 0x41, 0xb1, 0x69, 0x90, 0x2a, 0xd1, 0x8d, 0x6c, 0x0c, 0x91, 0x2a, 0xf3, 0x67, 0xe8, 0x52, 0x5d, + 0xec, 0xe3, 0x72, 0x22, 0xf6, 0x99, 0xfb, 0x9d, 0xab, 0x96, 0x09, 0x31, 0x22, 0x21, 0xf1, 0x51, + 0x32, 0x30, 0xb3, 0xb0, 0x74, 0xac, 0x98, 0x98, 0x10, 0x4a, 0x86, 0x7c, 0x0d, 0x94, 0xf3, 0xa5, + 0xae, 0x1b, 0xa9, 0x5d, 0xac, 0x9f, 0xdf, 0x7b, 0xf7, 0xee, 0xbd, 0xf3, 0x19, 0x3f, 0xc8, 0x23, + 0x32, 0x1a, 0x0d, 0x48, 0xf4, 0x21, 0x38, 0xde, 0x0d, 0xd4, 0x89, 0x9f, 0x49, 0xa1, 0x84, 0xbd, + 0x7a, 0x01, 0xfb, 0xc7, 0xbb, 0xee, 0x46, 0x24, 0x20, 0x11, 0x10, 0x24, 0xc0, 0xe6, 0xaa, 0x04, + 0x58, 0x21, 0x73, 0xdd, 0xca, 0x6a, 0x46, 0x53, 0x0a, 0x1c, 0x0c, 0xe7, 0x54, 0x9d, 0x4f, 0x33, + 0xba, 0x60, 0x1a, 0x4c, 0x30, 0xa1, 0xc7, 0x60, 0x3e, 0x19, 0xb4, 0x59, 0x6c, 0x72, 0x54, 0x10, + 0xc5, 0x8b, 0xa1, 0xd6, 0x49, 0xc2, 0x53, 0x11, 0xe8, 0x67, 0x01, 0xb5, 0xbe, 0x21, 0x7c, 0xbf, + 0x0f, 0xec, 0x6d, 0x16, 0x13, 0x45, 0x0f, 0x88, 0x24, 0x09, 0xd8, 0x7b, 0xd8, 0x22, 0xb9, 0x1a, + 0x0a, 0xc9, 0xd5, 0xa9, 0x83, 0xb6, 0xd1, 0x8e, 0xd5, 0x73, 0x7e, 0xff, 0xe8, 0x34, 0x8c, 0xd7, + 0xcb, 0x38, 0x96, 0x14, 0xe0, 0xb5, 0x92, 0x3c, 0x65, 0x61, 0x29, 0xb5, 0xbb, 0xb8, 0x9e, 0x69, + 0x07, 0xe7, 0xd6, 0x36, 0xda, 0xb9, 0xd7, 0x6d, 0xf8, 0x97, 0xdb, 0xfb, 0x85, 0x7b, 0xef, 0xf6, + 0xd9, 0xdf, 0xad, 0x5a, 0x68, 0x94, 0xfb, 0x6b, 0x5f, 0x66, 0xe3, 0x76, 0xe9, 0xd1, 0x6a, 0xe2, + 0x8d, 0x2b, 0x71, 0x42, 0x0a, 0x99, 0x48, 0x81, 0xb6, 0x7e, 0x21, 0xbc, 0xde, 0x07, 0xf6, 0x4e, + 0x28, 0x1a, 0x52, 0x12, 0x87, 0x14, 0xf2, 0x91, 0xb2, 0x9f, 0xe1, 0x3a, 0x70, 0x96, 0x52, 0x79, + 0x63, 0x52, 0xa3, 0xb3, 0x37, 0x31, 0x96, 0xf4, 0x63, 0x4e, 0x41, 0x1d, 0xf1, 0x58, 0x47, 0xb5, + 0x42, 0xcb, 0x20, 0xaf, 0xe2, 0xb9, 0xa1, 0xd4, 0xd6, 0xce, 0x8a, 0x6e, 0xe1, 0x54, 0x5b, 0x94, + 0x5b, 0x87, 0x46, 0xb7, 0xff, 0x74, 0xde, 0xc1, 0xb8, 0x7f, 0x9d, 0x8d, 0xdb, 0x0f, 0xcb, 0x2f, + 0xb6, 0x94, 0xb7, 0xf5, 0x02, 0x37, 0x97, 0xc0, 0x45, 0x45, 0xfb, 0x11, 0xb6, 0xde, 0xf3, 0x94, + 0x8c, 0xf8, 0x27, 0x1a, 0xeb, 0x3e, 0x77, 0xc3, 0x12, 0xe8, 0xfe, 0x44, 0x78, 0xa5, 0x0f, 0xcc, + 0x3e, 0xc4, 0x6b, 0x57, 0x0e, 0x61, 0xab, 0x9a, 0x71, 0x69, 0x03, 0xf7, 0xc9, 0x0d, 0x82, 0x8b, + 0x04, 0x6f, 0xf0, 0x6a, 0xe5, 0x2e, 0x6c, 0x2e, 0x2d, 0xbc, 0x4c, 0xbb, 0x8f, 0xaf, 0xa5, 0x17, + 0xae, 0xee, 0x9d, 0xcf, 0xb3, 0x71, 0x1b, 0xf5, 0x0e, 0xce, 0x26, 0x1e, 0x3a, 0x9f, 0x78, 0xe8, + 0xdf, 0xc4, 0x43, 0xdf, 0xa7, 0x5e, 0xed, 0x7c, 0xea, 0xd5, 0xfe, 0x4c, 0xbd, 0xda, 0xe1, 0x1e, + 0xe3, 0x6a, 0x98, 0x0f, 0xfc, 0x48, 0x24, 0x41, 0x96, 0xc3, 0x30, 0x1a, 0x12, 0x9e, 0xea, 0xa9, + 0xa3, 0xc7, 0x4e, 0x2a, 0x62, 0x1a, 0x9c, 0x04, 0xe5, 0xc9, 0xea, 0x1f, 0x61, 0x50, 0xd7, 0xb7, + 0xf8, 0xf9, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x27, 0x12, 0xf6, 0x0b, 0x7f, 0x03, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + // VoteReadResult submits one universal validator's observation of a read + // request's outcome on the destination chain. + VoteReadResult(ctx context.Context, in *MsgVoteReadResult, opts ...grpc.CallOption) (*MsgVoteReadResultResponse, error) + // UpdateParams defines a governance operation for updating the parameters. + // + // Since: cosmos-sdk 0.47 + UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) VoteReadResult(ctx context.Context, in *MsgVoteReadResult, opts ...grpc.CallOption) (*MsgVoteReadResultResponse, error) { + out := new(MsgVoteReadResultResponse) + err := c.cc.Invoke(ctx, "/ucallback.v1.Msg/VoteReadResult", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, "/ucallback.v1.Msg/UpdateParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // VoteReadResult submits one universal validator's observation of a read + // request's outcome on the destination chain. + VoteReadResult(context.Context, *MsgVoteReadResult) (*MsgVoteReadResultResponse, error) + // UpdateParams defines a governance operation for updating the parameters. + // + // Since: cosmos-sdk 0.47 + UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) VoteReadResult(ctx context.Context, req *MsgVoteReadResult) (*MsgVoteReadResultResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method VoteReadResult not implemented") +} +func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_VoteReadResult_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgVoteReadResult) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).VoteReadResult(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ucallback.v1.Msg/VoteReadResult", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).VoteReadResult(ctx, req.(*MsgVoteReadResult)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ucallback.v1.Msg/UpdateParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "ucallback.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "VoteReadResult", + Handler: _Msg_VoteReadResult_Handler, + }, + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ucallback/v1/tx.proto", +} + +func (m *MsgUpdateParams) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgVoteReadResult) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgVoteReadResult) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgVoteReadResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Result != nil { + { + size, err := m.Result.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.RequestId) > 0 { + i -= len(m.RequestId) + copy(dAtA[i:], m.RequestId) + i = encodeVarintTx(dAtA, i, uint64(len(m.RequestId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgVoteReadResultResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgVoteReadResultResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgVoteReadResultResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Finalized { + i-- + if m.Finalized { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgUpdateParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Params.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgUpdateParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgVoteReadResult) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.RequestId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Result != nil { + l = m.Result.Size() + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgVoteReadResultResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Finalized { + n += 2 + } + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgVoteReadResult) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgVoteReadResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgVoteReadResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RequestId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Result == nil { + m.Result = &ReadResult{} + } + if err := m.Result.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgVoteReadResultResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgVoteReadResultResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgVoteReadResultResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Finalized", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Finalized = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/ucallback/types/types.pb.go b/x/ucallback/types/types.pb.go new file mode 100644 index 00000000..1d039cb9 --- /dev/null +++ b/x/ucallback/types/types.pb.go @@ -0,0 +1,2280 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ucallback/v1/types.proto + +package types + +import ( + bytes "bytes" + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + types "github.com/pushchain/push-chain-node/x/uexecutor/types" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// ReadStatus is the outcome a universal validator observed for a read. +type ReadStatus int32 + +const ( + ReadStatus_READ_STATUS_UNSPECIFIED ReadStatus = 0 + ReadStatus_READ_STATUS_SUCCESS ReadStatus = 1 + ReadStatus_READ_STATUS_ERROR ReadStatus = 2 +) + +var ReadStatus_name = map[int32]string{ + 0: "READ_STATUS_UNSPECIFIED", + 1: "READ_STATUS_SUCCESS", + 2: "READ_STATUS_ERROR", +} + +var ReadStatus_value = map[string]int32{ + "READ_STATUS_UNSPECIFIED": 0, + "READ_STATUS_SUCCESS": 1, + "READ_STATUS_ERROR": 2, +} + +func (x ReadStatus) String() string { + return proto.EnumName(ReadStatus_name, int32(x)) +} + +func (ReadStatus) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_bdb5182bd84a8426, []int{0} +} + +// UniversalReadStatus is the lifecycle state of a read request on Push Chain. +type UniversalReadStatus int32 + +const ( + UniversalReadStatus_UNIVERSAL_READ_STATUS_UNSPECIFIED UniversalReadStatus = 0 + UniversalReadStatus_UNIVERSAL_READ_STATUS_PENDING UniversalReadStatus = 1 + UniversalReadStatus_UNIVERSAL_READ_STATUS_VOTING UniversalReadStatus = 2 + UniversalReadStatus_UNIVERSAL_READ_STATUS_FULFILLED UniversalReadStatus = 3 + UniversalReadStatus_UNIVERSAL_READ_STATUS_EXPIRED UniversalReadStatus = 4 + UniversalReadStatus_UNIVERSAL_READ_STATUS_FAILED UniversalReadStatus = 5 +) + +var UniversalReadStatus_name = map[int32]string{ + 0: "UNIVERSAL_READ_STATUS_UNSPECIFIED", + 1: "UNIVERSAL_READ_STATUS_PENDING", + 2: "UNIVERSAL_READ_STATUS_VOTING", + 3: "UNIVERSAL_READ_STATUS_FULFILLED", + 4: "UNIVERSAL_READ_STATUS_EXPIRED", + 5: "UNIVERSAL_READ_STATUS_FAILED", +} + +var UniversalReadStatus_value = map[string]int32{ + "UNIVERSAL_READ_STATUS_UNSPECIFIED": 0, + "UNIVERSAL_READ_STATUS_PENDING": 1, + "UNIVERSAL_READ_STATUS_VOTING": 2, + "UNIVERSAL_READ_STATUS_FULFILLED": 3, + "UNIVERSAL_READ_STATUS_EXPIRED": 4, + "UNIVERSAL_READ_STATUS_FAILED": 5, +} + +func (x UniversalReadStatus) String() string { + return proto.EnumName(UniversalReadStatus_name, int32(x)) +} + +func (UniversalReadStatus) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_bdb5182bd84a8426, []int{1} +} + +// ReadRequest is one external read requested by an app on Push Chain. +// +// Every field is derived from the UniversalCallback.ReadRequested event, except +// created_at_height / requested_tx_hash / requested_log_index which come from the +// block the log was emitted in. +// +// NOTE: callbackGasLimit is deliberately absent. It is an argument to +// requestExternalReadSelf and is stored in the contract's _pending entry, but it is +// NOT emitted in ReadRequested. It has to be read back via getPendingRead(requestId) +// at fulfilment time, when the gas budget is actually needed. +type ReadRequest struct { + RequestId string `protobuf:"bytes,1,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + DestinationChain string `protobuf:"bytes,2,opt,name=destination_chain,json=destinationChain,proto3" json:"destination_chain,omitempty"` + Owner []byte `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"` + Query []byte `protobuf:"bytes,4,opt,name=query,proto3" json:"query,omitempty"` + MinConfirmations uint32 `protobuf:"varint,5,opt,name=min_confirmations,json=minConfirmations,proto3" json:"min_confirmations,omitempty"` + DestinationBlockHeight uint64 `protobuf:"varint,6,opt,name=destination_block_height,json=destinationBlockHeight,proto3" json:"destination_block_height,omitempty"` + ExpiryBlockHeight uint64 `protobuf:"varint,7,opt,name=expiry_block_height,json=expiryBlockHeight,proto3" json:"expiry_block_height,omitempty"` + CreatedAtHeight uint64 `protobuf:"varint,8,opt,name=created_at_height,json=createdAtHeight,proto3" json:"created_at_height,omitempty"` + // Bookkeeping — recorded for operators, not consumed by universal validators. + CallbackTarget string `protobuf:"bytes,9,opt,name=callback_target,json=callbackTarget,proto3" json:"callback_target,omitempty"` + OriginalFunder string `protobuf:"bytes,10,opt,name=original_funder,json=originalFunder,proto3" json:"original_funder,omitempty"` + FeesDeposited string `protobuf:"bytes,11,opt,name=fees_deposited,json=feesDeposited,proto3" json:"fees_deposited,omitempty"` + MaxFee string `protobuf:"bytes,12,opt,name=max_fee,json=maxFee,proto3" json:"max_fee,omitempty"` + RequestedTxHash string `protobuf:"bytes,13,opt,name=requested_tx_hash,json=requestedTxHash,proto3" json:"requested_tx_hash,omitempty"` + RequestedLogIndex uint64 `protobuf:"varint,14,opt,name=requested_log_index,json=requestedLogIndex,proto3" json:"requested_log_index,omitempty"` +} + +func (m *ReadRequest) Reset() { *m = ReadRequest{} } +func (m *ReadRequest) String() string { return proto.CompactTextString(m) } +func (*ReadRequest) ProtoMessage() {} +func (*ReadRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_bdb5182bd84a8426, []int{0} +} +func (m *ReadRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ReadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ReadRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ReadRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReadRequest.Merge(m, src) +} +func (m *ReadRequest) XXX_Size() int { + return m.Size() +} +func (m *ReadRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ReadRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ReadRequest proto.InternalMessageInfo + +func (m *ReadRequest) GetRequestId() string { + if m != nil { + return m.RequestId + } + return "" +} + +func (m *ReadRequest) GetDestinationChain() string { + if m != nil { + return m.DestinationChain + } + return "" +} + +func (m *ReadRequest) GetOwner() []byte { + if m != nil { + return m.Owner + } + return nil +} + +func (m *ReadRequest) GetQuery() []byte { + if m != nil { + return m.Query + } + return nil +} + +func (m *ReadRequest) GetMinConfirmations() uint32 { + if m != nil { + return m.MinConfirmations + } + return 0 +} + +func (m *ReadRequest) GetDestinationBlockHeight() uint64 { + if m != nil { + return m.DestinationBlockHeight + } + return 0 +} + +func (m *ReadRequest) GetExpiryBlockHeight() uint64 { + if m != nil { + return m.ExpiryBlockHeight + } + return 0 +} + +func (m *ReadRequest) GetCreatedAtHeight() uint64 { + if m != nil { + return m.CreatedAtHeight + } + return 0 +} + +func (m *ReadRequest) GetCallbackTarget() string { + if m != nil { + return m.CallbackTarget + } + return "" +} + +func (m *ReadRequest) GetOriginalFunder() string { + if m != nil { + return m.OriginalFunder + } + return "" +} + +func (m *ReadRequest) GetFeesDeposited() string { + if m != nil { + return m.FeesDeposited + } + return "" +} + +func (m *ReadRequest) GetMaxFee() string { + if m != nil { + return m.MaxFee + } + return "" +} + +func (m *ReadRequest) GetRequestedTxHash() string { + if m != nil { + return m.RequestedTxHash + } + return "" +} + +func (m *ReadRequest) GetRequestedLogIndex() uint64 { + if m != nil { + return m.RequestedLogIndex + } + return 0 +} + +// ReadResult is the observation a universal validator votes on. +// +// Fields 1-4 are covered by the ballot key, so they must be byte-identical across +// validators for a ballot to converge. There is deliberately no error message field: +// local error text differs per node and would prevent agreement. +type ReadResult struct { + Status ReadStatus `protobuf:"varint,1,opt,name=status,proto3,enum=ucallback.v1.ReadStatus" json:"status,omitempty"` + ResultData []byte `protobuf:"bytes,2,opt,name=result_data,json=resultData,proto3" json:"result_data,omitempty"` + ObservedBlockHeight uint64 `protobuf:"varint,3,opt,name=observed_block_height,json=observedBlockHeight,proto3" json:"observed_block_height,omitempty"` + ObservedBlockHash []byte `protobuf:"bytes,4,opt,name=observed_block_hash,json=observedBlockHash,proto3" json:"observed_block_hash,omitempty"` + // v2 ONLY — always empty in v1. See AggregateValue. + Aggregates []*AggregateValue `protobuf:"bytes,5,rep,name=aggregates,proto3" json:"aggregates,omitempty"` +} + +func (m *ReadResult) Reset() { *m = ReadResult{} } +func (m *ReadResult) String() string { return proto.CompactTextString(m) } +func (*ReadResult) ProtoMessage() {} +func (*ReadResult) Descriptor() ([]byte, []int) { + return fileDescriptor_bdb5182bd84a8426, []int{1} +} +func (m *ReadResult) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ReadResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ReadResult.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ReadResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReadResult.Merge(m, src) +} +func (m *ReadResult) XXX_Size() int { + return m.Size() +} +func (m *ReadResult) XXX_DiscardUnknown() { + xxx_messageInfo_ReadResult.DiscardUnknown(m) +} + +var xxx_messageInfo_ReadResult proto.InternalMessageInfo + +func (m *ReadResult) GetStatus() ReadStatus { + if m != nil { + return m.Status + } + return ReadStatus_READ_STATUS_UNSPECIFIED +} + +func (m *ReadResult) GetResultData() []byte { + if m != nil { + return m.ResultData + } + return nil +} + +func (m *ReadResult) GetObservedBlockHeight() uint64 { + if m != nil { + return m.ObservedBlockHeight + } + return 0 +} + +func (m *ReadResult) GetObservedBlockHash() []byte { + if m != nil { + return m.ObservedBlockHash + } + return nil +} + +func (m *ReadResult) GetAggregates() []*AggregateValue { + if m != nil { + return m.Aggregates + } + return nil +} + +// AggregateValue is one field the module combines across validators instead of +// requiring byte-equality on — a price, say, where honest nodes legitimately differ. +// +// NOT USED IN v1. The universal client rejects any extract mode other than IDENTICAL +// (externalchains/web2/read_envelope.go), so this list is always empty today. The field +// is reserved now because adding it later would change how ballots are keyed on a live +// chain, which is consensus-breaking. In v1 the ballot key covers all of fields 1-4; in +// v2 it must cover only fields 1-4 with `aggregates` EXCLUDED, so computing the key over +// "the identical subset" from the start keeps v2 purely additive. +// +// v2 ALSO REQUIRES REPLACING THE BALLOT MECHANISM, not just populating this field. +// Ballots today store a binary VoteResult{SUCCESS|FAILURE} against an ID that encodes the +// observation, so distinct observations produce distinct ballots and none reaches quorum +// when validators report different numbers. Ballots therefore cannot retain per-validator +// values, which is exactly what a median needs. v2 has to keep each validator's +// AggregateValue set in module state and reduce at quorum — the pattern x/uexecutor +// already uses for gas-price medians in keeper/chain_meta.go, which bypasses ballots for +// the same reason. +type AggregateValue struct { + ExtractIndex uint32 `protobuf:"varint,1,opt,name=extract_index,json=extractIndex,proto3" json:"extract_index,omitempty"` + Mode uint32 `protobuf:"varint,2,opt,name=mode,proto3" json:"mode,omitempty"` + Value []byte `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *AggregateValue) Reset() { *m = AggregateValue{} } +func (m *AggregateValue) String() string { return proto.CompactTextString(m) } +func (*AggregateValue) ProtoMessage() {} +func (*AggregateValue) Descriptor() ([]byte, []int) { + return fileDescriptor_bdb5182bd84a8426, []int{2} +} +func (m *AggregateValue) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AggregateValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AggregateValue.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AggregateValue) XXX_Merge(src proto.Message) { + xxx_messageInfo_AggregateValue.Merge(m, src) +} +func (m *AggregateValue) XXX_Size() int { + return m.Size() +} +func (m *AggregateValue) XXX_DiscardUnknown() { + xxx_messageInfo_AggregateValue.DiscardUnknown(m) +} + +var xxx_messageInfo_AggregateValue proto.InternalMessageInfo + +func (m *AggregateValue) GetExtractIndex() uint32 { + if m != nil { + return m.ExtractIndex + } + return 0 +} + +func (m *AggregateValue) GetMode() uint32 { + if m != nil { + return m.Mode + } + return 0 +} + +func (m *AggregateValue) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +// UniversalRead is the full lifecycle record of one read request. +// +// The read-side sibling of uexecutor's UniversalTx, but deliberately not the same +// shape: a read is triggered by a Push Chain event rather than an external inbound, +// performs no external write, and settles in exactly one Push Chain transaction. +type UniversalRead struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Request *ReadRequest `protobuf:"bytes,2,opt,name=request,proto3" json:"request,omitempty"` + Result *ReadResult `protobuf:"bytes,3,opt,name=result,proto3" json:"result,omitempty"` + Status UniversalReadStatus `protobuf:"varint,4,opt,name=status,proto3,enum=ucallback.v1.UniversalReadStatus" json:"status,omitempty"` + BallotKey string `protobuf:"bytes,5,opt,name=ballot_key,json=ballotKey,proto3" json:"ballot_key,omitempty"` + // Push Chain execution attempts — fulfilExternalCallback and expireExternalRead. + // Repeated because fulfilment can be retried and may be followed by an expiry. + PcTx []*types.PCTx `protobuf:"bytes,6,rep,name=pc_tx,json=pcTx,proto3" json:"pc_tx,omitempty"` +} + +func (m *UniversalRead) Reset() { *m = UniversalRead{} } +func (m *UniversalRead) String() string { return proto.CompactTextString(m) } +func (*UniversalRead) ProtoMessage() {} +func (*UniversalRead) Descriptor() ([]byte, []int) { + return fileDescriptor_bdb5182bd84a8426, []int{3} +} +func (m *UniversalRead) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UniversalRead) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UniversalRead.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UniversalRead) XXX_Merge(src proto.Message) { + xxx_messageInfo_UniversalRead.Merge(m, src) +} +func (m *UniversalRead) XXX_Size() int { + return m.Size() +} +func (m *UniversalRead) XXX_DiscardUnknown() { + xxx_messageInfo_UniversalRead.DiscardUnknown(m) +} + +var xxx_messageInfo_UniversalRead proto.InternalMessageInfo + +func (m *UniversalRead) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +func (m *UniversalRead) GetRequest() *ReadRequest { + if m != nil { + return m.Request + } + return nil +} + +func (m *UniversalRead) GetResult() *ReadResult { + if m != nil { + return m.Result + } + return nil +} + +func (m *UniversalRead) GetStatus() UniversalReadStatus { + if m != nil { + return m.Status + } + return UniversalReadStatus_UNIVERSAL_READ_STATUS_UNSPECIFIED +} + +func (m *UniversalRead) GetBallotKey() string { + if m != nil { + return m.BallotKey + } + return "" +} + +func (m *UniversalRead) GetPcTx() []*types.PCTx { + if m != nil { + return m.PcTx + } + return nil +} + +func init() { + proto.RegisterEnum("ucallback.v1.ReadStatus", ReadStatus_name, ReadStatus_value) + proto.RegisterEnum("ucallback.v1.UniversalReadStatus", UniversalReadStatus_name, UniversalReadStatus_value) + proto.RegisterType((*ReadRequest)(nil), "ucallback.v1.ReadRequest") + proto.RegisterType((*ReadResult)(nil), "ucallback.v1.ReadResult") + proto.RegisterType((*AggregateValue)(nil), "ucallback.v1.AggregateValue") + proto.RegisterType((*UniversalRead)(nil), "ucallback.v1.UniversalRead") +} + +func init() { proto.RegisterFile("ucallback/v1/types.proto", fileDescriptor_bdb5182bd84a8426) } + +var fileDescriptor_bdb5182bd84a8426 = []byte{ + // 939 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x55, 0xcd, 0x6e, 0xdb, 0x46, + 0x10, 0x36, 0x65, 0xd9, 0xa9, 0x56, 0x3f, 0x96, 0xd6, 0x49, 0xcd, 0xba, 0xb1, 0x2c, 0x27, 0x08, + 0x22, 0xb8, 0x88, 0xd4, 0x38, 0x40, 0xd1, 0x06, 0xbd, 0x28, 0x12, 0xd5, 0x08, 0x15, 0x1c, 0x61, + 0x25, 0x19, 0x45, 0x2f, 0x8b, 0x15, 0x39, 0xa6, 0x08, 0x53, 0xa4, 0x42, 0x2e, 0x55, 0xea, 0x09, + 0x0a, 0xf4, 0xd4, 0x47, 0xe8, 0xa1, 0x87, 0x1e, 0x7a, 0xe8, 0x03, 0xf4, 0x01, 0x7a, 0xcc, 0xb1, + 0xc7, 0xc2, 0x3e, 0xb4, 0xd7, 0xbe, 0x41, 0xb1, 0x4b, 0x52, 0xa1, 0x5c, 0xf9, 0x22, 0x2c, 0xbf, + 0xef, 0xdb, 0x99, 0xd9, 0xf9, 0x66, 0xb5, 0x48, 0x0d, 0x74, 0x66, 0xdb, 0x13, 0xa6, 0x5f, 0x35, + 0x17, 0xcf, 0x9b, 0x7c, 0x39, 0x07, 0xbf, 0x31, 0xf7, 0x5c, 0xee, 0xe2, 0xc2, 0x8a, 0x69, 0x2c, + 0x9e, 0x1f, 0xde, 0x37, 0x5d, 0xd3, 0x95, 0x44, 0x53, 0xac, 0x22, 0xcd, 0x61, 0x85, 0xcd, 0x2c, + 0xc7, 0x6d, 0xca, 0xdf, 0x18, 0x52, 0x03, 0x08, 0x41, 0x0f, 0xb8, 0xeb, 0xdd, 0x0a, 0xf8, 0xe8, + 0xf7, 0x2c, 0xca, 0x13, 0x60, 0x06, 0x81, 0xb7, 0x01, 0xf8, 0x1c, 0x1f, 0x21, 0xe4, 0x45, 0x4b, + 0x6a, 0x19, 0xaa, 0x52, 0x53, 0xea, 0x39, 0x92, 0x8b, 0x91, 0x9e, 0x81, 0x3f, 0x41, 0x15, 0x03, + 0x7c, 0x6e, 0x39, 0x8c, 0x5b, 0xae, 0x43, 0xf5, 0x29, 0xb3, 0x1c, 0x35, 0x23, 0x55, 0xe5, 0x14, + 0xd1, 0x16, 0x38, 0xbe, 0x8f, 0x76, 0xdc, 0xef, 0x1c, 0xf0, 0xd4, 0xed, 0x9a, 0x52, 0x2f, 0x90, + 0xe8, 0x43, 0xa0, 0x6f, 0x03, 0xf0, 0x96, 0x6a, 0x36, 0x42, 0xe5, 0x87, 0x08, 0x3c, 0xb3, 0x1c, + 0xaa, 0xbb, 0xce, 0xa5, 0xe5, 0xcd, 0x64, 0x10, 0x5f, 0xdd, 0xa9, 0x29, 0xf5, 0x22, 0x29, 0xcf, + 0x2c, 0xa7, 0x9d, 0xc6, 0xf1, 0xe7, 0x48, 0x4d, 0x57, 0x31, 0xb1, 0x5d, 0xfd, 0x8a, 0x4e, 0xc1, + 0x32, 0xa7, 0x5c, 0xdd, 0xad, 0x29, 0xf5, 0x2c, 0xf9, 0x30, 0xc5, 0xbf, 0x12, 0xf4, 0x6b, 0xc9, + 0xe2, 0x06, 0xda, 0x87, 0x70, 0x6e, 0x79, 0xcb, 0xf5, 0x4d, 0xf7, 0xe4, 0xa6, 0x4a, 0x44, 0xa5, + 0xf5, 0xa7, 0xa8, 0xa2, 0x7b, 0xc0, 0x38, 0x18, 0x94, 0xf1, 0x44, 0xfd, 0x81, 0x54, 0xef, 0xc5, + 0x44, 0x8b, 0xc7, 0xda, 0xa7, 0x68, 0x2f, 0x31, 0x87, 0x72, 0xe6, 0x99, 0xc0, 0xd5, 0x9c, 0xec, + 0x4c, 0x29, 0x81, 0x47, 0x12, 0x15, 0x42, 0xd7, 0xb3, 0x4c, 0xcb, 0x61, 0x36, 0xbd, 0x0c, 0x1c, + 0x03, 0x3c, 0x15, 0x45, 0xc2, 0x04, 0xee, 0x4a, 0x14, 0x3f, 0x41, 0xa5, 0x4b, 0x00, 0x9f, 0x1a, + 0x30, 0x77, 0x7d, 0x8b, 0x83, 0xa1, 0xe6, 0xa5, 0xae, 0x28, 0xd0, 0x4e, 0x02, 0xe2, 0x03, 0x74, + 0x6f, 0xc6, 0x42, 0x7a, 0x09, 0xa0, 0x16, 0x24, 0xbf, 0x3b, 0x63, 0x61, 0x17, 0x40, 0x54, 0x1f, + 0x5b, 0x07, 0x06, 0xe5, 0x21, 0x9d, 0x32, 0x7f, 0xaa, 0x16, 0xa5, 0x64, 0x6f, 0x45, 0x8c, 0xc2, + 0xd7, 0xcc, 0x9f, 0x8a, 0xce, 0xbc, 0xd7, 0xda, 0xae, 0x49, 0x2d, 0xc7, 0x80, 0x50, 0x2d, 0x45, + 0x9d, 0x59, 0x51, 0x7d, 0xd7, 0xec, 0x09, 0xe2, 0x65, 0xf6, 0x9f, 0x9f, 0x8e, 0x95, 0x47, 0xdf, + 0x67, 0x10, 0x8a, 0xc6, 0xc7, 0x0f, 0x6c, 0x8e, 0x3f, 0x45, 0xbb, 0x3e, 0x67, 0x3c, 0xf0, 0xe5, + 0xe4, 0x94, 0xce, 0xd4, 0x46, 0x7a, 0x5e, 0x1b, 0x42, 0x39, 0x94, 0x3c, 0x89, 0x75, 0xf8, 0x18, + 0xe5, 0x3d, 0xb9, 0x97, 0x1a, 0x8c, 0x33, 0x39, 0x4a, 0x05, 0x82, 0x22, 0xa8, 0xc3, 0x38, 0xc3, + 0x67, 0xe8, 0x81, 0x3b, 0xf1, 0xc1, 0x5b, 0x80, 0xb1, 0xee, 0xd9, 0xb6, 0xac, 0x6c, 0x3f, 0x21, + 0x6f, 0xb9, 0x7c, 0x7b, 0x8f, 0x38, 0x79, 0x34, 0x70, 0x95, 0xf5, 0x1d, 0xe2, 0xec, 0x5f, 0x22, + 0xc4, 0x4c, 0xd3, 0x03, 0x93, 0x71, 0x10, 0x53, 0xb7, 0x5d, 0xcf, 0x9f, 0x3d, 0x5c, 0x2f, 0xbd, + 0x95, 0xf0, 0x17, 0xcc, 0x0e, 0x80, 0xa4, 0xf4, 0x71, 0x27, 0x00, 0x95, 0xd6, 0x35, 0xf8, 0x31, + 0x2a, 0x42, 0xc8, 0x3d, 0xa6, 0xf3, 0xb8, 0x97, 0x8a, 0x1c, 0xe7, 0x42, 0x0c, 0xca, 0x36, 0x62, + 0x8c, 0xb2, 0x33, 0xd7, 0x00, 0x79, 0xf0, 0x22, 0x91, 0x6b, 0x71, 0x43, 0x16, 0x22, 0x42, 0x72, + 0x6f, 0xe4, 0x47, 0x9c, 0xe6, 0xd7, 0x0c, 0x2a, 0x8e, 0x1d, 0x6b, 0x01, 0x9e, 0xcf, 0x6c, 0xd1, + 0x4f, 0x5c, 0x42, 0x99, 0xd5, 0x4d, 0xcd, 0x58, 0x06, 0x7e, 0x81, 0xee, 0xc5, 0x6e, 0xc9, 0xa0, + 0xf9, 0xb3, 0x8f, 0xfe, 0x6f, 0x42, 0x7c, 0xdb, 0x49, 0xa2, 0x14, 0xc6, 0x45, 0x3d, 0x97, 0x39, + 0xf3, 0x9b, 0x8c, 0x8b, 0x2c, 0x26, 0xb1, 0x0e, 0x7f, 0xb1, 0xb2, 0x3a, 0x2b, 0xad, 0x3e, 0x59, + 0xdf, 0xb1, 0x56, 0xe3, 0x2d, 0xcf, 0x8f, 0x10, 0x9a, 0x30, 0xdb, 0x76, 0x39, 0xbd, 0x82, 0xa5, + 0xbc, 0xe4, 0x39, 0x92, 0x8b, 0x90, 0xaf, 0x61, 0x89, 0x9f, 0xa2, 0x9d, 0xb9, 0x4e, 0x79, 0xa8, + 0xee, 0x4a, 0x23, 0x70, 0x63, 0xf5, 0xe7, 0x25, 0x02, 0x0f, 0xda, 0xa3, 0x90, 0x64, 0xe7, 0xfa, + 0x28, 0x7c, 0x79, 0x22, 0x3a, 0xf2, 0xc3, 0xdf, 0xbf, 0x9d, 0xa6, 0xfe, 0x2f, 0x83, 0x24, 0x2f, + 0xf5, 0x80, 0x19, 0xa7, 0x34, 0x1a, 0xcf, 0xa8, 0x00, 0xfc, 0x31, 0x3a, 0x20, 0x5a, 0xab, 0x43, + 0x87, 0xa3, 0xd6, 0x68, 0x3c, 0xa4, 0xe3, 0xf3, 0xe1, 0x40, 0x6b, 0xf7, 0xba, 0x3d, 0xad, 0x53, + 0xde, 0xc2, 0x07, 0x68, 0x3f, 0x4d, 0x0e, 0xc7, 0xed, 0xb6, 0x36, 0x1c, 0x96, 0x15, 0xfc, 0x00, + 0x55, 0xd2, 0x84, 0x46, 0xc8, 0x1b, 0x52, 0xce, 0x1c, 0x66, 0x7f, 0xf9, 0xb9, 0xaa, 0x9c, 0xfe, + 0xab, 0xa0, 0xfd, 0x0d, 0x67, 0xc5, 0x4f, 0xd0, 0xc9, 0xf8, 0xbc, 0x77, 0xa1, 0x91, 0x61, 0xab, + 0x4f, 0xef, 0x4e, 0x7a, 0x82, 0x8e, 0x36, 0xcb, 0x06, 0xda, 0x79, 0xa7, 0x77, 0xfe, 0x55, 0x59, + 0xc1, 0x35, 0xf4, 0x70, 0xb3, 0xe4, 0xe2, 0xcd, 0x48, 0x28, 0x32, 0xf8, 0x31, 0x3a, 0xde, 0xac, + 0xe8, 0x8e, 0xfb, 0xdd, 0x5e, 0xbf, 0xaf, 0x75, 0xca, 0xdb, 0x77, 0x67, 0xd2, 0xbe, 0x19, 0xf4, + 0x88, 0xd6, 0x29, 0x67, 0xef, 0xce, 0xd4, 0x6d, 0xf5, 0x44, 0x90, 0x9d, 0xe8, 0xcc, 0xaf, 0x06, + 0x7f, 0x5c, 0x57, 0x95, 0x77, 0xd7, 0x55, 0xe5, 0xaf, 0xeb, 0xaa, 0xf2, 0xe3, 0x4d, 0x75, 0xeb, + 0xdd, 0x4d, 0x75, 0xeb, 0xcf, 0x9b, 0xea, 0xd6, 0xb7, 0x9f, 0x99, 0x16, 0x9f, 0x06, 0x93, 0x86, + 0xee, 0xce, 0x9a, 0xf3, 0xc0, 0x9f, 0xca, 0xf7, 0x41, 0xae, 0x9e, 0xc9, 0xe5, 0x33, 0xc7, 0x35, + 0xa0, 0x19, 0x36, 0xdf, 0xfb, 0x25, 0xdf, 0xa2, 0xc9, 0xae, 0x7c, 0x8c, 0x5e, 0xfc, 0x17, 0x00, + 0x00, 0xff, 0xff, 0x80, 0x05, 0x37, 0x8d, 0xf9, 0x06, 0x00, 0x00, +} + +func (this *ReadRequest) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*ReadRequest) + if !ok { + that2, ok := that.(ReadRequest) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.RequestId != that1.RequestId { + return false + } + if this.DestinationChain != that1.DestinationChain { + return false + } + if !bytes.Equal(this.Owner, that1.Owner) { + return false + } + if !bytes.Equal(this.Query, that1.Query) { + return false + } + if this.MinConfirmations != that1.MinConfirmations { + return false + } + if this.DestinationBlockHeight != that1.DestinationBlockHeight { + return false + } + if this.ExpiryBlockHeight != that1.ExpiryBlockHeight { + return false + } + if this.CreatedAtHeight != that1.CreatedAtHeight { + return false + } + if this.CallbackTarget != that1.CallbackTarget { + return false + } + if this.OriginalFunder != that1.OriginalFunder { + return false + } + if this.FeesDeposited != that1.FeesDeposited { + return false + } + if this.MaxFee != that1.MaxFee { + return false + } + if this.RequestedTxHash != that1.RequestedTxHash { + return false + } + if this.RequestedLogIndex != that1.RequestedLogIndex { + return false + } + return true +} +func (this *ReadResult) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*ReadResult) + if !ok { + that2, ok := that.(ReadResult) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Status != that1.Status { + return false + } + if !bytes.Equal(this.ResultData, that1.ResultData) { + return false + } + if this.ObservedBlockHeight != that1.ObservedBlockHeight { + return false + } + if !bytes.Equal(this.ObservedBlockHash, that1.ObservedBlockHash) { + return false + } + if len(this.Aggregates) != len(that1.Aggregates) { + return false + } + for i := range this.Aggregates { + if !this.Aggregates[i].Equal(that1.Aggregates[i]) { + return false + } + } + return true +} +func (this *AggregateValue) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*AggregateValue) + if !ok { + that2, ok := that.(AggregateValue) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.ExtractIndex != that1.ExtractIndex { + return false + } + if this.Mode != that1.Mode { + return false + } + if !bytes.Equal(this.Value, that1.Value) { + return false + } + return true +} +func (this *UniversalRead) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*UniversalRead) + if !ok { + that2, ok := that.(UniversalRead) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Id != that1.Id { + return false + } + if !this.Request.Equal(that1.Request) { + return false + } + if !this.Result.Equal(that1.Result) { + return false + } + if this.Status != that1.Status { + return false + } + if this.BallotKey != that1.BallotKey { + return false + } + if len(this.PcTx) != len(that1.PcTx) { + return false + } + for i := range this.PcTx { + if !this.PcTx[i].Equal(that1.PcTx[i]) { + return false + } + } + return true +} +func (m *ReadRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ReadRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ReadRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.RequestedLogIndex != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.RequestedLogIndex)) + i-- + dAtA[i] = 0x70 + } + if len(m.RequestedTxHash) > 0 { + i -= len(m.RequestedTxHash) + copy(dAtA[i:], m.RequestedTxHash) + i = encodeVarintTypes(dAtA, i, uint64(len(m.RequestedTxHash))) + i-- + dAtA[i] = 0x6a + } + if len(m.MaxFee) > 0 { + i -= len(m.MaxFee) + copy(dAtA[i:], m.MaxFee) + i = encodeVarintTypes(dAtA, i, uint64(len(m.MaxFee))) + i-- + dAtA[i] = 0x62 + } + if len(m.FeesDeposited) > 0 { + i -= len(m.FeesDeposited) + copy(dAtA[i:], m.FeesDeposited) + i = encodeVarintTypes(dAtA, i, uint64(len(m.FeesDeposited))) + i-- + dAtA[i] = 0x5a + } + if len(m.OriginalFunder) > 0 { + i -= len(m.OriginalFunder) + copy(dAtA[i:], m.OriginalFunder) + i = encodeVarintTypes(dAtA, i, uint64(len(m.OriginalFunder))) + i-- + dAtA[i] = 0x52 + } + if len(m.CallbackTarget) > 0 { + i -= len(m.CallbackTarget) + copy(dAtA[i:], m.CallbackTarget) + i = encodeVarintTypes(dAtA, i, uint64(len(m.CallbackTarget))) + i-- + dAtA[i] = 0x4a + } + if m.CreatedAtHeight != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.CreatedAtHeight)) + i-- + dAtA[i] = 0x40 + } + if m.ExpiryBlockHeight != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.ExpiryBlockHeight)) + i-- + dAtA[i] = 0x38 + } + if m.DestinationBlockHeight != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.DestinationBlockHeight)) + i-- + dAtA[i] = 0x30 + } + if m.MinConfirmations != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.MinConfirmations)) + i-- + dAtA[i] = 0x28 + } + if len(m.Query) > 0 { + i -= len(m.Query) + copy(dAtA[i:], m.Query) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Query))) + i-- + dAtA[i] = 0x22 + } + if len(m.Owner) > 0 { + i -= len(m.Owner) + copy(dAtA[i:], m.Owner) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Owner))) + i-- + dAtA[i] = 0x1a + } + if len(m.DestinationChain) > 0 { + i -= len(m.DestinationChain) + copy(dAtA[i:], m.DestinationChain) + i = encodeVarintTypes(dAtA, i, uint64(len(m.DestinationChain))) + i-- + dAtA[i] = 0x12 + } + if len(m.RequestId) > 0 { + i -= len(m.RequestId) + copy(dAtA[i:], m.RequestId) + i = encodeVarintTypes(dAtA, i, uint64(len(m.RequestId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ReadResult) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ReadResult) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ReadResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Aggregates) > 0 { + for iNdEx := len(m.Aggregates) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Aggregates[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if len(m.ObservedBlockHash) > 0 { + i -= len(m.ObservedBlockHash) + copy(dAtA[i:], m.ObservedBlockHash) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ObservedBlockHash))) + i-- + dAtA[i] = 0x22 + } + if m.ObservedBlockHeight != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.ObservedBlockHeight)) + i-- + dAtA[i] = 0x18 + } + if len(m.ResultData) > 0 { + i -= len(m.ResultData) + copy(dAtA[i:], m.ResultData) + i = encodeVarintTypes(dAtA, i, uint64(len(m.ResultData))) + i-- + dAtA[i] = 0x12 + } + if m.Status != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Status)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *AggregateValue) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AggregateValue) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AggregateValue) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Value) > 0 { + i -= len(m.Value) + copy(dAtA[i:], m.Value) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Value))) + i-- + dAtA[i] = 0x1a + } + if m.Mode != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Mode)) + i-- + dAtA[i] = 0x10 + } + if m.ExtractIndex != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.ExtractIndex)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *UniversalRead) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UniversalRead) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UniversalRead) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.PcTx) > 0 { + for iNdEx := len(m.PcTx) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.PcTx[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if len(m.BallotKey) > 0 { + i -= len(m.BallotKey) + copy(dAtA[i:], m.BallotKey) + i = encodeVarintTypes(dAtA, i, uint64(len(m.BallotKey))) + i-- + dAtA[i] = 0x2a + } + if m.Status != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Status)) + i-- + dAtA[i] = 0x20 + } + if m.Result != nil { + { + size, err := m.Result.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.Request != nil { + { + size, err := m.Request.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTypes(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Id) > 0 { + i -= len(m.Id) + copy(dAtA[i:], m.Id) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Id))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintTypes(dAtA []byte, offset int, v uint64) int { + offset -= sovTypes(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ReadRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.RequestId) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.DestinationChain) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Owner) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.Query) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.MinConfirmations != 0 { + n += 1 + sovTypes(uint64(m.MinConfirmations)) + } + if m.DestinationBlockHeight != 0 { + n += 1 + sovTypes(uint64(m.DestinationBlockHeight)) + } + if m.ExpiryBlockHeight != 0 { + n += 1 + sovTypes(uint64(m.ExpiryBlockHeight)) + } + if m.CreatedAtHeight != 0 { + n += 1 + sovTypes(uint64(m.CreatedAtHeight)) + } + l = len(m.CallbackTarget) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.OriginalFunder) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.FeesDeposited) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.MaxFee) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.RequestedTxHash) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.RequestedLogIndex != 0 { + n += 1 + sovTypes(uint64(m.RequestedLogIndex)) + } + return n +} + +func (m *ReadResult) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Status != 0 { + n += 1 + sovTypes(uint64(m.Status)) + } + l = len(m.ResultData) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.ObservedBlockHeight != 0 { + n += 1 + sovTypes(uint64(m.ObservedBlockHeight)) + } + l = len(m.ObservedBlockHash) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if len(m.Aggregates) > 0 { + for _, e := range m.Aggregates { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + return n +} + +func (m *AggregateValue) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ExtractIndex != 0 { + n += 1 + sovTypes(uint64(m.ExtractIndex)) + } + if m.Mode != 0 { + n += 1 + sovTypes(uint64(m.Mode)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + return n +} + +func (m *UniversalRead) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Id) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.Request != nil { + l = m.Request.Size() + n += 1 + l + sovTypes(uint64(l)) + } + if m.Result != nil { + l = m.Result.Size() + n += 1 + l + sovTypes(uint64(l)) + } + if m.Status != 0 { + n += 1 + sovTypes(uint64(m.Status)) + } + l = len(m.BallotKey) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if len(m.PcTx) > 0 { + for _, e := range m.PcTx { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + return n +} + +func sovTypes(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTypes(x uint64) (n int) { + return sovTypes(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *ReadRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ReadRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ReadRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RequestId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DestinationChain", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DestinationChain = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Owner = append(m.Owner[:0], dAtA[iNdEx:postIndex]...) + if m.Owner == nil { + m.Owner = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Query = append(m.Query[:0], dAtA[iNdEx:postIndex]...) + if m.Query == nil { + m.Query = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinConfirmations", wireType) + } + m.MinConfirmations = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinConfirmations |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DestinationBlockHeight", wireType) + } + m.DestinationBlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DestinationBlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ExpiryBlockHeight", wireType) + } + m.ExpiryBlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ExpiryBlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CreatedAtHeight", wireType) + } + m.CreatedAtHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CreatedAtHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CallbackTarget", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CallbackTarget = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OriginalFunder", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OriginalFunder = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FeesDeposited", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FeesDeposited = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxFee", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MaxFee = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestedTxHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RequestedTxHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 14: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RequestedLogIndex", wireType) + } + m.RequestedLogIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RequestedLogIndex |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ReadResult) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ReadResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ReadResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + m.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Status |= ReadStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ResultData", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ResultData = append(m.ResultData[:0], dAtA[iNdEx:postIndex]...) + if m.ResultData == nil { + m.ResultData = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ObservedBlockHeight", wireType) + } + m.ObservedBlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ObservedBlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObservedBlockHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ObservedBlockHash = append(m.ObservedBlockHash[:0], dAtA[iNdEx:postIndex]...) + if m.ObservedBlockHash == nil { + m.ObservedBlockHash = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Aggregates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Aggregates = append(m.Aggregates, &AggregateValue{}) + if err := m.Aggregates[len(m.Aggregates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AggregateValue) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AggregateValue: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AggregateValue: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ExtractIndex", wireType) + } + m.ExtractIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ExtractIndex |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType) + } + m.Mode = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Mode |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...) + if m.Value == nil { + m.Value = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UniversalRead) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UniversalRead: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UniversalRead: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Request", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Request == nil { + m.Request = &ReadRequest{} + } + if err := m.Request.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Result == nil { + m.Result = &ReadResult{} + } + if err := m.Result.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + m.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Status |= UniversalReadStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BallotKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BallotKey = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PcTx", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PcTx = append(m.PcTx, &types.PCTx{}) + if err := m.PcTx[len(m.PcTx)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTypes(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTypes + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTypes + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTypes + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTypes = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTypes = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/uregistry/types/constants.go b/x/uregistry/types/constants.go index 95d5f9e1..68d1499e 100644 --- a/x/uregistry/types/constants.go +++ b/x/uregistry/types/constants.go @@ -51,6 +51,16 @@ var SYSTEM_CONTRACTS = map[string]ContractAddresses{ ProxyAdmin: "0xF2000000000000000000000000000000000000C1", Implementation: "0xF1000000000000000000000000000000000000C1", }, + // UNIVERSAL_CALLBACK is the read-request contract x/ucallback listens to. + // Promoted out of the RESERVED_C2 auto-reservation below: same address, same + // admin, same implementation, and (until the real contract ships) the same + // placeholder bytecode — so genesis state is byte-identical to before the + // rename, and chains that already deployed 0xC2 skip it as already-deployed. + "UNIVERSAL_CALLBACK": { + Address: "0x00000000000000000000000000000000000000C2", + ProxyAdmin: "0xF2000000000000000000000000000000000000C2", + Implementation: "0xF1000000000000000000000000000000000000C2", + }, "VAULT_PC": { Address: "0x00000000000000000000000000000000000000B0", ProxyAdmin: "0xF2000000000000000000000000000000000000b0", @@ -142,7 +152,8 @@ func reservedProxyBytecode(slotByte byte) []byte { // Range policy: // - 0xA0-0xAF: Proxy Admins / low-level modules (0xAA pre-occupied by uexecutor) // - 0xB0-0xBF: Vaults + utility (0xB0 = VAULT_PC; 0xB1 = VAULT_PC20; 0xB2 = RESERVED_2; 0xBC = UNIVERSAL_BATCH_CALL) -// - 0xC0-0xCF: Chain abstraction (0xC0 = UNIVERSAL_CORE; 0xC1 = UNIVERSAL_GATEWAY_PC) +// - 0xC0-0xCF: Chain abstraction (0xC0 = UNIVERSAL_CORE; 0xC1 = UNIVERSAL_GATEWAY_PC; +// 0xC2 = UNIVERSAL_CALLBACK) // - 0xD0-0xFF: NOT reserved — left to other chains / future debug use // // Choice of full triples (vs bytecode-only): future activation of a reserved @@ -154,6 +165,16 @@ func init() { 0xB0: true, 0xB1: true, 0xB2: true, // VAULT_PC / VAULT_PC20 / RESERVED_2 0xBC: true, 0xC0: true, 0xC1: true, // UNIVERSAL_CORE, UNIVERSAL_GATEWAY_PC + 0xC2: true, // UNIVERSAL_CALLBACK + } + + // Placeholder bytecode for UNIVERSAL_CALLBACK, identical to what RESERVED_C2 + // carried before the promotion. Replaced with the real compiled contract in + // the commit that deploys it. + BYTECODE["UNIVERSAL_CALLBACK"] = ByteCodes{ + IMPL_RUNTIME: ReservedImplRuntimeBytecode, + PROXY_RUNTIME: reservedProxyBytecode(0xC2), + ADMIN_RUNTIME: ProxyAdminRuntimeBytecode, } for _, hi := range []byte{0xA, 0xB, 0xC} { diff --git a/x/uregistry/types/constants_test.go b/x/uregistry/types/constants_test.go index 83183626..5f345bda 100644 --- a/x/uregistry/types/constants_test.go +++ b/x/uregistry/types/constants_test.go @@ -22,6 +22,7 @@ func TestReservedSlots_FullTripleDeployedForEveryUnoccupiedABCSlot(t *testing.T) 0xAA: true, 0xB0: true, 0xB1: true, 0xB2: true, 0xBC: true, 0xC0: true, 0xC1: true, + 0xC2: true, // promoted to UNIVERSAL_CALLBACK; covered by the test below } for _, hi := range []byte{0xA, 0xB, 0xC} { @@ -166,3 +167,40 @@ func TestReservedSlots_BytecodeIsCaseInsensitiveAcrossSlots(t *testing.T) { require.Equal(t, src, upperBytes, "UPPERCASE hex must decode to identical bytes (case-insensitive)") require.Equal(t, src, mixedBytes, "MiXeD hex must decode to identical bytes (case-insensitive)") } + +// TestUniversalCallbackSlot_KeepsReservedTriple asserts that promoting 0xC2 out of +// the RESERVED_* auto-reservation did not weaken it. The slot must still carry a +// complete proxy + admin + impl triple with the same addresses RESERVED_C2 had, so +// the promotion is a rename and genesis state is unchanged. +func TestUniversalCallbackSlot_KeepsReservedTriple(t *testing.T) { + addrs, ok := SYSTEM_CONTRACTS["UNIVERSAL_CALLBACK"] + require.True(t, ok, "UNIVERSAL_CALLBACK missing from SYSTEM_CONTRACTS") + + require.Equal(t, "0x00000000000000000000000000000000000000c2", strings.ToLower(addrs.Address)) + require.Equal(t, "0xf2000000000000000000000000000000000000c2", strings.ToLower(addrs.ProxyAdmin)) + require.Equal(t, "0xf1000000000000000000000000000000000000c2", strings.ToLower(addrs.Implementation)) + + bc, ok := BYTECODE["UNIVERSAL_CALLBACK"] + require.True(t, ok, "BYTECODE missing entry UNIVERSAL_CALLBACK") + require.NotEmpty(t, bc.IMPL_RUNTIME) + require.NotEmpty(t, bc.PROXY_RUNTIME) + require.NotEmpty(t, bc.ADMIN_RUNTIME) + + // the proxy must embed ITS OWN admin, not the 0xB0 template's + require.Contains(t, + strings.ToLower(hex.EncodeToString(bc.PROXY_RUNTIME)), + "f2000000000000000000000000000000000000c2") + + // the old name must be gone, or genesis would deploy the slot twice + _, stale := SYSTEM_CONTRACTS["RESERVED_C2"] + require.False(t, stale, "RESERVED_C2 must not coexist with UNIVERSAL_CALLBACK") +} + +// The address x/ucallback filters logs on must round-trip through common.Address, +// since the hook compares against a parsed address, not the raw string. +func TestUniversalCallbackAddress_RoundTrips(t *testing.T) { + addr := common.HexToAddress(SYSTEM_CONTRACTS["UNIVERSAL_CALLBACK"].Address) + require.Equal(t, + "0x00000000000000000000000000000000000000c2", + strings.ToLower(addr.Hex())) +} diff --git a/x/uvalidator/types/ballot.pb.go b/x/uvalidator/types/ballot.pb.go index 111e99fc..4fd07807 100644 --- a/x/uvalidator/types/ballot.pb.go +++ b/x/uvalidator/types/ballot.pb.go @@ -72,6 +72,7 @@ const ( BallotObservationType_BALLOT_OBSERVATION_TYPE_OUTBOUND_TX BallotObservationType = 2 BallotObservationType_BALLOT_OBSERVATION_TYPE_TSS_KEY BallotObservationType = 3 BallotObservationType_BALLOT_OBSERVATION_TYPE_FUND_MIGRATION BallotObservationType = 4 + BallotObservationType_BALLOT_OBSERVATION_TYPE_READ_RESULT BallotObservationType = 5 ) var BallotObservationType_name = map[int32]string{ @@ -80,6 +81,7 @@ var BallotObservationType_name = map[int32]string{ 2: "BALLOT_OBSERVATION_TYPE_OUTBOUND_TX", 3: "BALLOT_OBSERVATION_TYPE_TSS_KEY", 4: "BALLOT_OBSERVATION_TYPE_FUND_MIGRATION", + 5: "BALLOT_OBSERVATION_TYPE_READ_RESULT", } var BallotObservationType_value = map[string]int32{ @@ -88,6 +90,7 @@ var BallotObservationType_value = map[string]int32{ "BALLOT_OBSERVATION_TYPE_OUTBOUND_TX": 2, "BALLOT_OBSERVATION_TYPE_TSS_KEY": 3, "BALLOT_OBSERVATION_TYPE_FUND_MIGRATION": 4, + "BALLOT_OBSERVATION_TYPE_READ_RESULT": 5, } func (x BallotObservationType) String() string { @@ -242,46 +245,47 @@ func init() { func init() { proto.RegisterFile("uvalidator/v1/ballot.proto", fileDescriptor_b9f9c8e0d3c818f3) } var fileDescriptor_b9f9c8e0d3c818f3 = []byte{ - // 616 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x94, 0xcf, 0x4e, 0xdb, 0x4a, - 0x14, 0xc6, 0x63, 0x07, 0x72, 0x2f, 0x73, 0xef, 0x0d, 0x66, 0x80, 0x5b, 0x93, 0xaa, 0x6e, 0x04, - 0x15, 0xa4, 0x48, 0xc4, 0x05, 0x16, 0x5d, 0xe7, 0xcf, 0x40, 0xdd, 0xa6, 0x76, 0xea, 0x19, 0x23, - 0xe8, 0x66, 0xe4, 0x24, 0xa3, 0xd8, 0xaa, 0xc9, 0x44, 0xf6, 0x24, 0x82, 0xb7, 0xe8, 0x1b, 0x74, - 0xd3, 0x45, 0x1f, 0xa5, 0x4b, 0x96, 0x5d, 0x56, 0xb0, 0xe9, 0x3b, 0x74, 0x53, 0x79, 0xcc, 0x9f, - 0x24, 0x85, 0x6e, 0xac, 0xa3, 0xef, 0xf7, 0x9d, 0xf3, 0xf9, 0x68, 0x3c, 0x06, 0xa5, 0xd1, 0xd8, - 0x8f, 0xc2, 0x9e, 0x2f, 0x78, 0x6c, 0x8e, 0x77, 0xcd, 0x8e, 0x1f, 0x45, 0x5c, 0x54, 0x87, 0x31, - 0x17, 0x1c, 0xfe, 0x77, 0xc7, 0xaa, 0xe3, 0xdd, 0xd2, 0x4a, 0x9f, 0xf7, 0xb9, 0x24, 0x66, 0x5a, - 0x65, 0xa6, 0xd2, 0x92, 0x7f, 0x1a, 0x0e, 0xb8, 0x29, 0x9f, 0x99, 0xb4, 0xfe, 0x53, 0x05, 0x85, - 0xba, 0x1c, 0x04, 0x8b, 0x40, 0x0d, 0x7b, 0xba, 0x52, 0x56, 0x2a, 0x0b, 0xae, 0x1a, 0xf6, 0x20, - 0x02, 0xff, 0x64, 0x11, 0x54, 0x9c, 0x0f, 0x99, 0xae, 0x96, 0x95, 0x4a, 0x71, 0xef, 0x59, 0x75, - 0x2a, 0xa8, 0x9a, 0xf5, 0x3a, 0x9d, 0x84, 0xc5, 0x63, 0x5f, 0x84, 0x7c, 0x40, 0xce, 0x87, 0xcc, - 0x05, 0x59, 0x63, 0x5a, 0xc3, 0x2d, 0xb0, 0xc8, 0xa2, 0xb0, 0x1f, 0x76, 0x22, 0x46, 0xc7, 0x5c, - 0xb0, 0x38, 0xd1, 0xf3, 0xe5, 0x7c, 0x65, 0xc1, 0x2d, 0xde, 0xc8, 0x47, 0x52, 0x85, 0x26, 0x98, - 0x4f, 0x79, 0xa2, 0xcf, 0x95, 0xf3, 0x95, 0xe2, 0xde, 0xda, 0x4c, 0x52, 0xea, 0x72, 0x59, 0x32, - 0x8a, 0x84, 0x9b, 0xf9, 0xe0, 0x73, 0xa0, 0x8d, 0xb9, 0x08, 0x07, 0x7d, 0x2a, 0x82, 0x98, 0x25, - 0x01, 0x8f, 0x7a, 0xfa, 0x7c, 0x59, 0xa9, 0xe4, 0xdd, 0xc5, 0x4c, 0x27, 0x37, 0x32, 0xdc, 0x07, - 0x85, 0x44, 0xf8, 0x62, 0x94, 0xe8, 0x05, 0xb9, 0xc6, 0xe3, 0x7b, 0xd7, 0xc0, 0xd2, 0xe2, 0x5e, - 0x5b, 0xe1, 0x0b, 0xb0, 0xd2, 0x89, 0x78, 0xf7, 0x03, 0x0d, 0x58, 0xd8, 0x0f, 0x04, 0xed, 0xc6, - 0xcc, 0x17, 0xac, 0xa7, 0xff, 0x25, 0x33, 0xa0, 0x64, 0xaf, 0x24, 0x6a, 0x64, 0x04, 0x56, 0xc1, - 0xf2, 0x54, 0x07, 0x3b, 0x1b, 0x86, 0xf1, 0xb9, 0xfe, 0xb7, 0x6c, 0x58, 0x9a, 0x68, 0x40, 0x12, - 0x6c, 0x7f, 0x52, 0xc0, 0xbf, 0x93, 0xd1, 0xf0, 0x09, 0x58, 0xab, 0xd7, 0x5a, 0x2d, 0x87, 0x50, - 0x4c, 0x6a, 0xc4, 0xc3, 0xd4, 0xb3, 0x71, 0x1b, 0x35, 0xac, 0x03, 0x0b, 0x35, 0xb5, 0x1c, 0x5c, - 0x03, 0xab, 0xd3, 0xb8, 0x8d, 0xec, 0xa6, 0x65, 0x1f, 0x6a, 0x0a, 0xd4, 0xc1, 0xca, 0x0c, 0xaa, - 0x61, 0x8c, 0x9a, 0x9a, 0x0a, 0x4b, 0xe0, 0xff, 0x69, 0xe2, 0xa2, 0xd7, 0xa8, 0x41, 0x50, 0x53, - 0xcb, 0xff, 0x3e, 0x10, 0x1d, 0xb7, 0x2d, 0x17, 0x35, 0xb5, 0xb9, 0xd2, 0xdc, 0x97, 0xcf, 0x86, - 0xb2, 0xfd, 0x43, 0x01, 0xab, 0xf7, 0x9e, 0x31, 0xdc, 0x02, 0x1b, 0xd7, 0xad, 0x4e, 0x1d, 0x23, - 0xf7, 0xa8, 0x46, 0x2c, 0xc7, 0xa6, 0xe4, 0xa4, 0x8d, 0x66, 0x5e, 0x7a, 0x13, 0xac, 0x3f, 0x64, - 0xb4, 0xec, 0xba, 0xe3, 0xd9, 0x4d, 0x4a, 0x8e, 0x35, 0xe5, 0x4f, 0x03, 0x1d, 0x8f, 0xdc, 0x1a, - 0x55, 0xb8, 0x01, 0x9e, 0x3e, 0x64, 0x24, 0x18, 0xd3, 0x37, 0xe8, 0x44, 0xcb, 0xc3, 0x6d, 0xb0, - 0xf9, 0x90, 0xe9, 0x20, 0x9d, 0xf4, 0xd6, 0x3a, 0x74, 0xa5, 0x76, 0xbb, 0x6a, 0x17, 0x80, 0xbb, - 0x6f, 0x2c, 0x3d, 0x89, 0x23, 0x87, 0x20, 0xea, 0x22, 0xec, 0xb5, 0x08, 0xb5, 0x1d, 0x42, 0x4f, - 0x10, 0xa1, 0xa9, 0x96, 0x2e, 0xf5, 0x08, 0x2c, 0x4f, 0x62, 0xec, 0x35, 0x1a, 0x08, 0x63, 0x4d, - 0x99, 0x05, 0x07, 0x35, 0xab, 0xe5, 0xb9, 0x48, 0x53, 0xb3, 0x90, 0xfa, 0xbb, 0xaf, 0x97, 0x86, - 0x72, 0x71, 0x69, 0x28, 0xdf, 0x2f, 0x0d, 0xe5, 0xe3, 0x95, 0x91, 0xbb, 0xb8, 0x32, 0x72, 0xdf, - 0xae, 0x8c, 0xdc, 0xfb, 0x97, 0xfd, 0x50, 0x04, 0xa3, 0x4e, 0xb5, 0xcb, 0x4f, 0xcd, 0xe1, 0x28, - 0x09, 0xba, 0x81, 0x1f, 0x0e, 0x64, 0xb5, 0x23, 0xcb, 0x9d, 0x01, 0xef, 0x31, 0xf3, 0xcc, 0x9c, - 0xf8, 0x09, 0xa4, 0xf7, 0x32, 0xe9, 0x14, 0xe4, 0x4d, 0xde, 0xff, 0x15, 0x00, 0x00, 0xff, 0xff, - 0x4e, 0x9b, 0x9c, 0x99, 0x1f, 0x04, 0x00, 0x00, + // 626 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x94, 0xc1, 0x4e, 0xdb, 0x4a, + 0x14, 0x86, 0x63, 0x27, 0xe4, 0x5e, 0xe6, 0xde, 0x1b, 0xcc, 0x00, 0xb7, 0x26, 0x55, 0xdd, 0x08, + 0x2a, 0x48, 0x91, 0x88, 0x0b, 0x2c, 0xba, 0x4e, 0xe2, 0x81, 0xba, 0x4d, 0xed, 0x74, 0x3c, 0x46, + 0xd0, 0xcd, 0xc8, 0x49, 0xac, 0xd8, 0xaa, 0xc9, 0x44, 0xf6, 0x24, 0x82, 0xb7, 0x68, 0x9f, 0xa0, + 0x9b, 0x2e, 0xfa, 0x28, 0x5d, 0xb2, 0xec, 0xb2, 0x82, 0xc7, 0xe8, 0xa6, 0xf2, 0x38, 0x94, 0x24, + 0x05, 0x36, 0xd1, 0xd1, 0xff, 0xfd, 0xe7, 0xfc, 0x39, 0x1e, 0x8f, 0x41, 0x79, 0x34, 0xf6, 0xa2, + 0xb0, 0xe7, 0x71, 0x16, 0xeb, 0xe3, 0x3d, 0xbd, 0xe3, 0x45, 0x11, 0xe3, 0xb5, 0x61, 0xcc, 0x38, + 0x83, 0xff, 0xdd, 0xb2, 0xda, 0x78, 0xaf, 0xbc, 0xda, 0x67, 0x7d, 0x26, 0x88, 0x9e, 0x56, 0x99, + 0xa9, 0xbc, 0xec, 0x9d, 0x85, 0x03, 0xa6, 0x8b, 0xdf, 0x4c, 0xda, 0xf8, 0x29, 0x83, 0x62, 0x43, + 0x0c, 0x82, 0x25, 0x20, 0x87, 0x3d, 0x55, 0xaa, 0x48, 0xd5, 0x45, 0x2c, 0x87, 0x3d, 0x88, 0xc0, + 0x3f, 0x59, 0x04, 0xe5, 0x17, 0x43, 0x5f, 0x95, 0x2b, 0x52, 0xb5, 0xb4, 0xff, 0xac, 0x36, 0x13, + 0x54, 0xcb, 0x7a, 0xed, 0x4e, 0xe2, 0xc7, 0x63, 0x8f, 0x87, 0x6c, 0x40, 0x2e, 0x86, 0x3e, 0x06, + 0x59, 0x63, 0x5a, 0xc3, 0x6d, 0xb0, 0xe4, 0x47, 0x61, 0x3f, 0xec, 0x44, 0x3e, 0x1d, 0x33, 0xee, + 0xc7, 0x89, 0x9a, 0xaf, 0xe4, 0xab, 0x8b, 0xb8, 0x74, 0x23, 0x1f, 0x0b, 0x15, 0xea, 0x60, 0x21, + 0xe5, 0x89, 0x5a, 0xa8, 0xe4, 0xab, 0xa5, 0xfd, 0xf5, 0xb9, 0xa4, 0xd4, 0x85, 0xfd, 0x64, 0x14, + 0x71, 0x9c, 0xf9, 0xe0, 0x73, 0xa0, 0x8c, 0x19, 0x0f, 0x07, 0x7d, 0xca, 0x83, 0xd8, 0x4f, 0x02, + 0x16, 0xf5, 0xd4, 0x85, 0x8a, 0x54, 0xcd, 0xe3, 0xa5, 0x4c, 0x27, 0x37, 0x32, 0x3c, 0x00, 0xc5, + 0x84, 0x7b, 0x7c, 0x94, 0xa8, 0x45, 0xb1, 0xc6, 0xe3, 0x3b, 0xd7, 0x70, 0x84, 0x05, 0x4f, 0xac, + 0xf0, 0x05, 0x58, 0xed, 0x44, 0xac, 0xfb, 0x81, 0x06, 0x7e, 0xd8, 0x0f, 0x38, 0xed, 0xc6, 0xbe, + 0xc7, 0xfd, 0x9e, 0xfa, 0x97, 0xc8, 0x80, 0x82, 0xbd, 0x12, 0xa8, 0x99, 0x11, 0x58, 0x03, 0x2b, + 0x33, 0x1d, 0xfe, 0xf9, 0x30, 0x8c, 0x2f, 0xd4, 0xbf, 0x45, 0xc3, 0xf2, 0x54, 0x03, 0x12, 0x60, + 0xe7, 0xb3, 0x04, 0xfe, 0x9d, 0x8e, 0x86, 0x4f, 0xc0, 0x7a, 0xa3, 0xde, 0x6a, 0xd9, 0x84, 0x3a, + 0xa4, 0x4e, 0x5c, 0x87, 0xba, 0x96, 0xd3, 0x46, 0x4d, 0xf3, 0xd0, 0x44, 0x86, 0x92, 0x83, 0xeb, + 0x60, 0x6d, 0x16, 0xb7, 0x91, 0x65, 0x98, 0xd6, 0x91, 0x22, 0x41, 0x15, 0xac, 0xce, 0xa1, 0xba, + 0xe3, 0x20, 0x43, 0x91, 0x61, 0x19, 0xfc, 0x3f, 0x4b, 0x30, 0x7a, 0x8d, 0x9a, 0x04, 0x19, 0x4a, + 0xfe, 0xcf, 0x81, 0xe8, 0xa4, 0x6d, 0x62, 0x64, 0x28, 0x85, 0x72, 0xe1, 0xeb, 0x17, 0x4d, 0xda, + 0xf9, 0x24, 0x83, 0xb5, 0x3b, 0xcf, 0x18, 0x6e, 0x83, 0xcd, 0x49, 0xab, 0xdd, 0x70, 0x10, 0x3e, + 0xae, 0x13, 0xd3, 0xb6, 0x28, 0x39, 0x6d, 0xa3, 0xb9, 0x3f, 0xbd, 0x05, 0x36, 0xee, 0x33, 0x9a, + 0x56, 0xc3, 0x76, 0x2d, 0x83, 0x92, 0x13, 0x45, 0x7a, 0x68, 0xa0, 0xed, 0x92, 0xdf, 0x46, 0x19, + 0x6e, 0x82, 0xa7, 0xf7, 0x19, 0x89, 0xe3, 0xd0, 0x37, 0xe8, 0x54, 0xc9, 0xc3, 0x1d, 0xb0, 0x75, + 0x9f, 0xe9, 0x30, 0x9d, 0xf4, 0xd6, 0x3c, 0xc2, 0x42, 0x53, 0x0a, 0x0f, 0x25, 0x63, 0x54, 0x37, + 0x28, 0x46, 0x8e, 0xdb, 0x22, 0xca, 0xc2, 0xe4, 0x99, 0x74, 0x01, 0xb8, 0x7d, 0x19, 0xd3, 0x23, + 0x3b, 0xb6, 0x09, 0x9a, 0x98, 0xa8, 0x65, 0x13, 0x7a, 0x8a, 0x08, 0x4d, 0xb5, 0x74, 0xfb, 0x47, + 0x60, 0x65, 0x1a, 0x3b, 0x6e, 0xb3, 0x89, 0x1c, 0x47, 0x91, 0xe6, 0xc1, 0x61, 0xdd, 0x6c, 0xb9, + 0x18, 0x29, 0x72, 0x16, 0xd2, 0x78, 0xf7, 0xed, 0x4a, 0x93, 0x2e, 0xaf, 0x34, 0xe9, 0xc7, 0x95, + 0x26, 0x7d, 0xbc, 0xd6, 0x72, 0x97, 0xd7, 0x5a, 0xee, 0xfb, 0xb5, 0x96, 0x7b, 0xff, 0xb2, 0x1f, + 0xf2, 0x60, 0xd4, 0xa9, 0x75, 0xd9, 0x99, 0x3e, 0x1c, 0x25, 0x41, 0x37, 0xf0, 0xc2, 0x81, 0xa8, + 0x76, 0x45, 0xb9, 0x3b, 0x60, 0x3d, 0x5f, 0x3f, 0xd7, 0xa7, 0xbe, 0x16, 0xe9, 0x05, 0x4e, 0x3a, + 0x45, 0x71, 0xe5, 0x0f, 0x7e, 0x05, 0x00, 0x00, 0xff, 0xff, 0x45, 0x8d, 0x9b, 0x0c, 0x48, 0x04, + 0x00, 0x00, } func (m *Ballot) Marshal() (dAtA []byte, err error) {