Skip to content

Proof verification fails for document query using startAt without where/orderBy #3078

Closed

Description

@thephez

Expected Behavior

A document query using startAt with only limit (no where or orderBy clauses) should return the requested document(s) successfully.

Current Behavior

The query fails with a GroveDB proof verification error:

grovedb: invalid proof: Invalid proof verification parameters: invalid proof error Proof returns more data than limit Some(1)

The same startAt value works correctly when combined with where and orderBy clauses.

Steps to Reproduce

Query that fails (bare startAt):

import { EvoSDK } from '@dashevo/evo-sdk';

const sdk = EvoSDK.testnetTrusted();
await sdk.connect();

const result = await sdk.documents.query({
  dataContractId: 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec',
  documentTypeName: 'domain',
  limit: 1,
  startAt: 'E8m6NCCnpschx4WRfk1uLMHqttqMJKPwYt8fWaVSJPrL',
});

Query that succeeds (same startAt with where/orderBy):

const result = await sdk.documents.query({
  dataContractId: 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec',
  documentTypeName: 'domain',
  limit: 1,
  startAt: 'E8m6NCCnpschx4WRfk1uLMHqttqMJKPwYt8fWaVSJPrL',
  where: [
    ['normalizedParentDomainName', '==', 'dash'],
    ['normalizedLabel', 'startsWith', 'tut0r1a1-test-'],
  ],
  orderBy: [['normalizedLabel', 'asc']],
});
Full runnable script
// demonstrate-startAt-issue.mjs
// Demonstrates the startAt bare query proof verification failure

import { EvoSDK } from '@dashevo/evo-sdk';

const DPNS_CONTRACT_ID = 'GWRSAVFMjXx8HpQFaNJMqBV7MBgMK4br5UESsB4S31Ec';
const KNOWN_DOCUMENT_ID = 'E8m6NCCnpschx4WRfk1uLMHqttqMJKPwYt8fWaVSJPrL';

async function main() {
  const sdk = EvoSDK.testnetTrusted();
  await sdk.connect();

  // -------------------------------------------------------
  // 1. FAILING QUERY — startAt with only limit (no where/orderBy)
  // -------------------------------------------------------
  console.log('--- Test 1: bare startAt query (expected to FAIL) ---');
  try {
    const result = await sdk.documents.query({
      dataContractId: DPNS_CONTRACT_ID,
      documentTypeName: 'domain',
      limit: 1,
      startAt: KNOWN_DOCUMENT_ID,
    });
    console.log('Unexpected success. Documents returned:', result.length);
  } catch (err) {
    console.error('FAILED as expected:', err.message);
    // Expected: "grovedb: invalid proof: Invalid proof verification
    //            parameters: invalid proof error Proof returns more
    //            data than limit Some(1)"
  }

  // -------------------------------------------------------
  // 2. PASSING QUERY — same startAt combined with where/orderBy
  // -------------------------------------------------------
  console.log('\n--- Test 2: startAt with where + orderBy (expected to PASS) ---');
  try {
    const result = await sdk.documents.query({
      dataContractId: DPNS_CONTRACT_ID,
      documentTypeName: 'domain',
      limit: 1,
      startAt: KNOWN_DOCUMENT_ID,
      where: [
        ['normalizedParentDomainName', '==', 'dash'],
        ['normalizedLabel', 'startsWith', 'tut0r1a1-test-'],
      ],
      orderBy: [['normalizedLabel', 'asc']],
    });
    console.log('SUCCESS. Documents returned:', result.size);
    if (result.size > 0) {
      const [id] = [...result.entries()][0];
      console.log('First document ID:', id.toString());
    }
  } catch (err) {
    console.error('Unexpected failure:', err.message);
  }
}

main().then(() => process.exit(0));

Possible Solution

The proof returned by the platform appears to contain more data than the requested limit when the query has no where/orderBy constraints but uses startAt pagination. The proof verification in GroveDB then rejects the proof because it exceeds the expected limit.

Context

The startAt field is a supported parameter in DocumentsQuery as defined in packages/wasm-sdk/src/queries/document.rs. The issue only manifests with the trusted client (proof-verifying path) — the query parameters themselves are valid.

Your Environment

  • SDK: @dashevo/evo-sdk v3.0.1
  • Network: testnet
  • Client: EvoSDK.testnetTrusted() (trusted/proof-verifying)
  • Node.js: v20

Activity

  1. added a commit that references this issue on Feb 18, 2026
  2. thephez commented on Oct 6, 2026

    @thephez
    CollaboratorAuthor

    Fixed in #4635 (GroveDB 6.0 adoption), first released in v4.2.0-beta.1.

    Root cause: a query with no where and no orderBy goes down the primary-key ($id tree) path. There, construct_path_query_operations always asked for limit + 1 to make room for the cursor row. On the $id tree, an inclusive startAt range already contains the cursor row, so the proof returned one more row than the verifier allowed (Proof returns more data than limit). rs-drive/src/query/mod.rs now adds that extra slot only when the cursor row isn't already in the page.

    This is a proof-generation change and isn't tied to a protocol version, so it applies once nodes run v4.2+. Networks still on v4.1.x will keep returning the error. test_proved_primary_key_cursor_pages_in_both_directions covers proving and verifying startAt/startAfter pages ordered by $id. It doesn't test the exact no-orderBy shape, but that shape takes the same path.

    Closing as fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions