XRPLF / rippled

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

account_lines with "peer" property returns 0 lines #4375

Closed nthpixel closed 1 year ago

nthpixel commented 1 year ago

Might be related to #4354

Encountered 2 wallets that should return trustlines when calling account_lines with the peer property set, but returns an empty array in the lines response. The wallets are raY2vCNbVUCiiEpQCU4VW7DS6p9easgFep and rQALHdY5js37FE152bVZgVN6KnmgQp615.

The peer address is rDbAT7ZnkBBxKYL8myUY68c1chaKLBbNKw and the token is xAliens.

Trustline for rQALHdY5js37FE152bVZgVN6KnmgQp615 has since been removed by the user.

Steps to Reproduce

https://xrpl.org/websocket-api-tool.html#account_lines

{
  "id": 2,
  "command": "account_lines",
  "account": "raY2vCNbVUCiiEpQCU4VW7DS6p9easgFep",
  "ledger_index": "validated",
  "peer": "rDbAT7ZnkBBxKYL8myUY68c1chaKLBbNKw"
}

Expected Result

Response with one object in the lines property.

Actual Result

{
  "id": 2,
  "result": {
    "account": "raY2vCNbVUCiiEpQCU4VW7DS6p9easgFep",
    "ledger_hash": "A4BE6C716193BC3EB77EDA1C87BFF667E2B00D61D2DB79A2D9C780C8500FED15",
    "ledger_index": 76885381,
    "limit": 200,
    "lines": [],
    "marker": "D0B826F773116336450B867B342D2D4411BD5EC8EF88B48DE3F3880356BF58B8,6",
    "validated": true,
    "warnings": [
      {
        "id": 1004,
        "message": "This is a reporting server.  The default behavior of a reporting server is to only return validated data. If you are looking for not yet validated data, include \"ledger_index : current\" in your request, which will cause this server to forward the request to a p2p node. If the forward is successful the response will include \"forwarded\" : \"true\""
      }
    ]
  },
  "status": "success",
  "type": "response"
}

This issue might be related to #4354 because both wallets have many trustlines and making subsequent calls with marker returns an error.

ximinez commented 1 year ago

4361 resolves the issue with the marker being invalid. It is expected that fewer than limit lines may be returned along with a marker, because of an optimization released in 1.8.2 to reduce load on rippled servers by counting all objects up to the limit instead of just the requested object type.

Please read the description of that PR for more details.

Additionally, I wrote a simple, ugly bash script to get the lines for the accounts mentioned above, iterating over the markers. I fired up an instance of rippled built from that PR #4361.

for acct in rQALHdY5js37FE152bVZgVN6KnmgQp615 raY2vCNbVUCiiEpQCU4VW7DS6p9easgFep; do echo Lines for $acct; marker=""; while l=$( rippled -q json account_lines '{"account": "'$acct'", "peer":"rDbAT7ZnkBBxKYL8myUY68c1chaKLBbNKw", "ledger_index": "validated" '"$marker"' }' ) ; do echo $l | jq ; marker=$( echo "$l" | jq '.result.marker' ); if [[ -z "$marker" || "$marker" == "null" ]]; then break; else marker=", \"marker\": $marker"; echo $marker; fi; done ; done

And here's the output:

Lines for rQALHdY5js37FE152bVZgVN6KnmgQp615
{
  "result": {
    "account": "rQALHdY5js37FE152bVZgVN6KnmgQp615",
    "ledger_hash": "23A959516872BD57EFEC550FA124686DEF35E9C9DF2D13F40C154902B438ECAD",
    "ledger_index": 76899512,
    "limit": 200,
    "lines": [],
    "marker": "F911506E4D7B4722F5EF66DBCBE36212AEDE04AB7A1D4315833103C49EC36ABB,11",
    "status": "success",
    "validated": true
  }
}
, "marker": "F911506E4D7B4722F5EF66DBCBE36212AEDE04AB7A1D4315833103C49EC36ABB,11"
{
  "result": {
    "account": "rQALHdY5js37FE152bVZgVN6KnmgQp615",
    "ledger_hash": "23A959516872BD57EFEC550FA124686DEF35E9C9DF2D13F40C154902B438ECAD",
    "ledger_index": 76899512,
    "lines": [],
    "status": "success",
    "validated": true
  }
}

Lines for raY2vCNbVUCiiEpQCU4VW7DS6p9easgFep
{
  "result": {
    "account": "raY2vCNbVUCiiEpQCU4VW7DS6p9easgFep",
    "ledger_hash": "23A959516872BD57EFEC550FA124686DEF35E9C9DF2D13F40C154902B438ECAD",
    "ledger_index": 76899512,
    "limit": 200,
    "lines": [],
    "marker": "D0B826F773116336450B867B342D2D4411BD5EC8EF88B48DE3F3880356BF58B8,6",
    "status": "success",
    "validated": true
  }
}
, "marker": "D0B826F773116336450B867B342D2D4411BD5EC8EF88B48DE3F3880356BF58B8,6"
{
  "result": {
    "account": "raY2vCNbVUCiiEpQCU4VW7DS6p9easgFep",
    "ledger_hash": "23A959516872BD57EFEC550FA124686DEF35E9C9DF2D13F40C154902B438ECAD",
    "ledger_index": 76899512,
    "limit": 200,
    "lines": [],
    "marker": "AC5A6CB527A4E1DD03F845C2BD630980BAEBA88F188391A68538F4A6409A7691,30",
    "status": "success",
    "validated": true
  }
}
, "marker": "AC5A6CB527A4E1DD03F845C2BD630980BAEBA88F188391A68538F4A6409A7691,30"
{
  "result": {
    "account": "raY2vCNbVUCiiEpQCU4VW7DS6p9easgFep",
    "ledger_hash": "23A959516872BD57EFEC550FA124686DEF35E9C9DF2D13F40C154902B438ECAD",
    "ledger_index": 76899512,
    "limit": 200,
    "lines": [],
    "marker": "6A8AD07C944442FC171191706734FBE4124C83FE8EC521A5F9033B107E5A322B,37",
    "status": "success",
    "validated": true
  }
}
, "marker": "6A8AD07C944442FC171191706734FBE4124C83FE8EC521A5F9033B107E5A322B,37"
{
  "result": {
    "account": "raY2vCNbVUCiiEpQCU4VW7DS6p9easgFep",
    "ledger_hash": "23A959516872BD57EFEC550FA124686DEF35E9C9DF2D13F40C154902B438ECAD",
    "ledger_index": 76899512,
    "lines": [
      {
        "account": "rDbAT7ZnkBBxKYL8myUY68c1chaKLBbNKw",
        "balance": "0",
        "currency": "78416C69656E7300000000000000000000000000",
        "limit": "10000",
        "limit_peer": "0",
        "no_ripple": true,
        "no_ripple_peer": false,
        "quality_in": 0,
        "quality_out": 0
      }
    ],
    "status": "success",
    "validated": true
  }
}

As noted, rQALHdY5js37FE152bVZgVN6KnmgQp615 doesn't have any lines against the given peer, but the other one does. However, it takes 4 iterations with markers to find it.

nthpixel commented 1 year ago

Thanks @ximinez. Do you know if there will be a fix for the account_lines command when using the peer parameter? I only need to verify the existence of one TL and would like to avoid iterating through markets if possible.

ximinez commented 1 year ago

@nthpixel I don't think there are any plans for a fix, because the behavior is intentional to the best of my knowledge. As pointed out in the description for #4361,

This issue derives from the optimization implemented in Enforce account RPC limits by account objects traversed. Previously, the ledger traversal would find up to limit account lines, and if there were more, the marker would be derived from the key of the next account line. After the change, ledger traversal would consider up to limit account objects of any kind found in the account's directory structure. If there were more, the marker would be derived from the key of the next object, regardless of type.

Note that because of this optimization it is expected that account_lines may return fewer than limit account lines, even 0, along with a marker indicating there are more available.

In other words, going through all of the account objects to find the line(s) that are associated with the peer would defeat the purpose of the linked optimization, which was implemented to reduce load on rippled servers.

I could see an argument for implementing functionality to return more lines on an admin connection (bypassing the optimization), but I don't know how complicated that would be to implement, and it would require running your own instance of rippled to take advantage of it.

nthpixel commented 1 year ago

@ximinez got it. Thank you for the explanation.

intelliot commented 1 year ago

Given that this is expected behavior, can we close this issue @nthpixel ?

nthpixel commented 1 year ago

@intelliot Yes, thank you.