-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add code sample showing how to walk an owner directory #3381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # Walk Owner Directory | ||
| Iterate over an account's owner directory and display how many ledger entries are in each page. In cases of highly active accounts, this can demonstrate the extent of "fragmentation" with skipped page numbers and non-full pages. | ||
|
|
||
| This code sample demonstrates the low-level structure of owner directories. If you don't need to see the breakdown by pages, you can use [`account_objects`](https://xrpl.org/docs/references/http-websocket-apis/public-api-methods/account-methods/account_objects) instead, since it provides a more convenient list of ledger entries attached to an account. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| // iterate-owner-directory.js | ||
| // Iterate over an account's owner directory and display how many ledger entries | ||
| // are in each page. In cases of highly active accounts, it can demonstrate | ||
| // the extent of "fragmentation" with skipped page numbers and non-full pages. | ||
|
|
||
| import xrpl from 'xrpl' | ||
|
|
||
| const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233') | ||
| await client.connect() | ||
|
|
||
| const owner = "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe" // Testnet faucet | ||
| // const owner = "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd" // TST issuer | ||
|
|
||
| // Set initial values for iterating | ||
| let sub_index = 0 // Directory root | ||
| let ledger_index = "validated" | ||
|
|
||
| // Query pages from the owner directory until they run out | ||
| console.log("Page #\t\t\tEntry count") | ||
| console.log("-----------------------------------") | ||
| while (true) { | ||
| // console.log(`Getting directory page ${sub_index}`) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer we keeping the logs (instead of commenting out), so that users are aware of what's going on. Also, for log before an async call, probably consider adding ... so users know to wait for the call to finish |
||
| const resp = await client.request({ | ||
| "command": "ledger_entry", | ||
| "directory": { | ||
| "owner": owner, | ||
| "sub_index": sub_index | ||
| }, | ||
| "ledger_index": ledger_index | ||
| }) | ||
| if (resp.error) { | ||
| console.error("ledger_entry failed with error",resp.error) | ||
| break | ||
| } | ||
|
|
||
| // Consistently iterate the same ledger: query by index after the first | ||
| if (ledger_index === "validated") { | ||
| ledger_index = resp.result.ledger_index | ||
| } | ||
|
|
||
| console.log(`${sub_index}\t\t\t${resp.result.node.Indexes.length}`) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I'd prefer this have a sentence format for clarity or a descriptor of some kind, similar to the commented out log below |
||
| // console.log(`This page contains ${resp.result.node.Indexes.length} items.`) | ||
|
|
||
| // Continue onto another page if this one has more | ||
| if (resp.result.node.hasOwnProperty("IndexNext")) { | ||
| // The directory continues onto another page. | ||
| // IndexNext is returned as hex but sub_index needs decimal | ||
| sub_index = parseInt(resp.result.node.IndexNext, 16) | ||
| } else { | ||
| console.info("This is the last page of the directory") | ||
| break | ||
| } | ||
| } | ||
|
|
||
| client.disconnect() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| { | ||
| "dependencies": { | ||
| "xrpl": "^4.4.3" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| # iterate-owner-directory.py | ||
| # Iterate over an account's owner directory and display how many ledger entries | ||
| # are in each page. In cases of highly active accounts, it can demonstrate | ||
| # the extent of "fragmentation" with skipped page numbers and non-full pages. | ||
| from xrpl.clients import JsonRpcClient | ||
| from xrpl.models.requests import LedgerEntry | ||
| from xrpl.clients import XRPLRequestFailureException | ||
|
|
||
| OWNER_ADDRESS = "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe" # Testnet faucet | ||
| # OWNER_ADDRESS = "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd" # TST issuer | ||
|
|
||
| client = JsonRpcClient("https://s.altnet.rippletest.net:51234/") | ||
|
|
||
| # Set initial values for iterating | ||
| sub_index = 0 # Directory root | ||
| ledger_index = "validated" | ||
|
|
||
| # Query pages from the owner directory until they run out | ||
| print("Page #\t\t\tEntry count") | ||
| print("-----------------------------------") | ||
| while True: | ||
| # Construct the LedgerEntry request for the directory page | ||
| directory_request = LedgerEntry( | ||
| directory={ | ||
| "owner": OWNER_ADDRESS, | ||
| "sub_index": sub_index | ||
| }, | ||
| ledger_index=ledger_index | ||
| ) | ||
|
|
||
| # Send the request | ||
| try: | ||
| response = client.request(directory_request) | ||
| except Exception as e: | ||
| print(f"\nError: ledger_entry failed: {e}") | ||
| break | ||
|
|
||
| # The 'ledger_index' is consistently set after the first successful query. | ||
| # This ensures subsequent pages are read from the same ledger version. | ||
| if ledger_index == "validated": | ||
| ledger_index = response.result["ledger_index"] | ||
|
|
||
| # The entries are stored in the 'Indexes' field of the 'DirectoryNode' | ||
| entry_count = len(response.result["node"]["Indexes"]) | ||
| print(f"{sub_index}\t\t\t{entry_count}") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here as other comment |
||
|
|
||
| # Check for the next page indicator | ||
| if "IndexNext" in response.result["node"].keys(): | ||
| # The directory continues onto another page. | ||
| # Convert IndexNext from hex to decimal for sub_index. | ||
| hex_next = response.result["node"]["IndexNext"] | ||
| sub_index = int(hex_next, 16) | ||
| else: | ||
| print("\nThis is the last page of the directory.") | ||
| break | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| xrpl-py==4.3.1 |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
constant should be upper case, same with 2 constants below