XRPLF / rippled

Decentralized cryptocurrency blockchain daemon implementing the XRP Ledger protocol in C++
https://xrpl.org
ISC License
4.48k stars 1.44k forks source link

Invalid "success" response from book_changes (possible race condition) #5033

Open mDuo13 opened 4 weeks ago

mDuo13 commented 4 weeks ago

Issue Description

When querying for a recent ledger by index, sometimes the result doesn't match the expected format.

Steps to Reproduce

Make WebSocket API requests such as the following, replacing the ledger index with the most recent one:

{
  "id": "example_book_changes",
  "command": "book_changes",
  "ledger_index": 88376663
}

The problem is intermittent, so it may take some tries to reproduce. Be sure to keep updating the ledger index with the most recent one as new ledgers are closed.

Expected Result

The API should either return a response in the expected format or an error message.

Example valid response (with non-empty changes):

{
  "id": "example_book_changes",
  "result": {
    "changes": [
      {
        "close": "1303424095097822e-4",
        "currency_a": "XRP_drops",
        "currency_b": "rchGBxcD1A1C2tdxF6papQYZ8kjRKMYcL/BTC",
        "high": "1304070002477734e-4",
        "low": "1302405543037992e-4",
        "open": "1303084400776639e-4",
        "volume_a": "60000000",
        "volume_b": "0.000460371"
      }
    ],
    "ledger_hash": "45765B07A378A94FCB6CEDD3D498E0CC15C73468F5F15AAA779079E67A234EB9",
    "ledger_index": 88376645,
    "ledger_time": 770512422,
    "type": "bookChanges"
  },
  "status": "success",
  "type": "response"
}

Example expected error response if the ledger index is too high:

{
  "error": "invalidParams",
  "error_code": 31,
  "error_message": "Ledger index too large",
  "id": "example_book_changes",
  "request": {
    "command": "book_changes",
    "id": "example_book_changes",
    "ledger_index": 88376663
  },
  "status": "error",
  "type": "response"
}

Actual Result

In some cases the response claims to be a success but it contains the wrong data, apparently some sort of status update on the status of acquiring the requested ledger. Looks like a Ledger Request Object.

{
  "id": "example_book_changes",
  "result": {
    "hash": "63C34CA1EE6CD80B89A035E077A0266BF2AF8F4A5CC729D1B595940D304BC05A",
    "have_header": true,
    "have_state": false,
    "have_transactions": false,
    "needed_state_hashes": [],
    "needed_transaction_hashes": [],
    "peers": 8,
    "timeouts": 1
  },
  "status": "success",
  "type": "response"
}

Environment

Tested using the xrplcluster.com servers running 2.2.0-rc1, but I think this API hasn't been changed much if at all since #4212 two years ago so the problems probably exist in older versions.

The s1.ripple.com cluster mostly goes to Clio servers; I haven't been able to reproduce on there.