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
rpc: add hidden getrawaddrman RPC to list addrman table entries #28523
rpc: add hidden getrawaddrman RPC to list addrman table entries #28523
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
concept ACK. I think it makes sense to expose more info about the addrman internals to allow for better observations & tooling |
Concept ACK |
48dfc81
to
da44fd3
Compare
I've also been hacking on a tool that visualizes addrman tables from the getaddrmaninfo verbose output in the browser. A wip version is on https://0xb10c.github.io/addrman-observer (github.com/0xB10C/addrman-observer). You can load dumps produced with |
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.
light ACK da44fd3
I intend to do more tests soon. Just tested it on a recent clearnet node and worked as expected.
Outputs: https://gist.github.com/brunoerg/e3643337b4c16923ee0e0f7e66bec4d9
ede5ecf
to
4307c8c
Compare
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.
Concept ACK
4307c8c
to
5c735ed
Compare
Thanks for the helpful review comments @brunoerg @ajtowns @amitiuttarwar. I think I have addressed them all in the most recent push:
I've also updated OP and the tool on https://0xb10c.github.io/addrman-observer. |
5c735ed
to
45a84d1
Compare
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.
tested ACK 45a84d1. Very cool to have!
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.
tested ACK 45a84d1. All the review comments are small style/doc things. The functionality looks good.
45a84d1
to
584e12d
Compare
Addresses the comments and nits. Thanks @amitiuttarwar, @stratospher, and @ajtowns. |
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.
crACK 2dc1a6d
Exposing address manager table entries in a hidden RPC allows to introspect addrman tables in tests and during development. As response JSON object the following FORMAT1 is choosen: { "table": { "<bucket>/<position>": { "address": "..", "port": .., ... }, "<bucket>/<position>": { "address": "..", "port": .., ... }, "<bucket>/<position>": { "address": "..", "port": .., ... }, ... } } An alternative would be FORMAT2 { "table": { "bucket": { "position": { "address": "..", "port": .., ... }, "position": { "address": "..", "port": .., ... }, .. }, "bucket": { "position": { "address": "..", "port": .., ... }, .. }, } } FORMAT1 and FORMAT2 have different encodings for the location of the address in the address manager. While FORMAT2 might be easier to process for downstream tools, it also mimics internal addrman mappings, which might change at some point. Users not interested in the address location can ignore the location key. They don't have to adapt to a new RPC response format, when the internal addrman layout changes. Additionally, FORMAT1 is also slightly easier to to iterate in downstream tools. The RPC response-building implemenation complexcity is lower with FORMAT1 as we can more easily build a "<bucket>/<position>" key than a multiple "bucket" objects with multiple "position" objects (FORMAT2).
Test that the getrawaddrman returns the addresses in the new and tried tables. We can't check the buckets and positions as these are not deterministic (yet).
2dc1a6d
to
352d5eb
Compare
With #28176 merged, I've rebased and now use the addrman table size constants in Re-reviewers might want to use |
reACK 352d5eb git range-diff shows the only difference since previous ACK @ 2dc1a6d is using the just-merged constants from Details
|
reACK 352d5eb |
reACK 352d5eb. |
ACK 352d5eb |
/*multiplicity_in=*/from_tried ? 1 : info.nRefCount, | ||
bucket, | ||
position); | ||
infos.push_back(std::make_pair(info, location)); |
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.
std::make_pair
isn't needed, starting with C++11, you can use emplace_back
. Fixed in #28583
assert_equal(result["source"], expected["source"]) | ||
assert_equal(result["source_network"], expected["source_network"]) | ||
# To avoid failing on slow test runners, use a 10s vspan here. | ||
assert_approx(result["time"], time.time(), vspan=10) |
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.
test 2023-10-12T14:27:36.383000Z TestFramework (DEBUG): Test that the getrawaddrman contains information about the addresses added in a previous test
node1 2023-10-12T14:27:36.384588Z [http] [httpserver.cpp:307] [http_request_cb] [http] Received a POST request for / from 127.0.0.1:37962
node1 2023-10-12T14:27:36.385003Z [httpworker.1] [rpc/request.cpp:181] [parse] [rpc] ThreadRPCServer method=getrawaddrman user=__cookie__
node1 2023-10-12T14:27:36.385345Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:36.385576Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.17ms)
node1 2023-10-12T14:27:36.988817Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:36.989107Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.17ms)
node1 2023-10-12T14:27:36.989261Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:36.989419Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.11ms)
node1 2023-10-12T14:27:37.083728Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.094364Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (10.42ms)
node1 2023-10-12T14:27:37.096430Z [http] [httpserver.cpp:307] [http_request_cb] [http] Received a POST request for / from 127.0.0.1:37962
node1 2023-10-12T14:27:37.096690Z [httpworker.1] [rpc/request.cpp:181] [parse] [rpc] ThreadRPCServer method=getaddrmaninfo user=__cookie__
node1 2023-10-12T14:27:37.096908Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.097184Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.21ms)
node1 2023-10-12T14:27:37.097247Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.097385Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.10ms)
node1 2023-10-12T14:27:37.097434Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.097563Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.10ms)
node1 2023-10-12T14:27:37.097606Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.097715Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.08ms)
node1 2023-10-12T14:27:37.097757Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.097854Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.07ms)
node1 2023-10-12T14:27:37.097883Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.175048Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (74.78ms)
node1 2023-10-12T14:27:37.179840Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.180187Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.27ms)
node1 2023-10-12T14:27:37.180243Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.180383Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.11ms)
node1 2023-10-12T14:27:37.180466Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.180610Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.11ms)
node1 2023-10-12T14:27:37.180652Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.180790Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.10ms)
node1 2023-10-12T14:27:37.180850Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.180980Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.09ms)
node1 2023-10-12T14:27:37.181023Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.181160Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.10ms)
node1 2023-10-12T14:27:37.181234Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.181363Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.09ms)
node1 2023-10-12T14:27:37.181406Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.181545Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.10ms)
node1 2023-10-12T14:27:37.181605Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.181738Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.10ms)
node1 2023-10-12T14:27:37.181780Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.181948Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.10ms)
node1 2023-10-12T14:27:37.182008Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.182146Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.10ms)
node1 2023-10-12T14:27:37.182187Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.182321Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.10ms)
node1 2023-10-12T14:27:37.182393Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.182545Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.11ms)
node1 2023-10-12T14:27:37.182588Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.182724Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.10ms)
node1 2023-10-12T14:27:37.182786Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.182926Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.10ms)
node1 2023-10-12T14:27:37.182975Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.183118Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.11ms)
node1 2023-10-12T14:27:37.183181Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.183325Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.10ms)
node1 2023-10-12T14:27:37.183393Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.183544Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.11ms)
node1 2023-10-12T14:27:37.183617Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.183772Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.12ms)
node1 2023-10-12T14:27:37.183812Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.183955Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.11ms)
node1 2023-10-12T14:27:37.184068Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.184220Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.12ms)
node1 2023-10-12T14:27:37.184261Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.184404Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.11ms)
node1 2023-10-12T14:27:37.184460Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.184607Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.11ms)
node1 2023-10-12T14:27:37.184646Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.184790Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.11ms)
node1 2023-10-12T14:27:37.184868Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.185043Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.14ms)
node1 2023-10-12T14:27:37.185086Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.185255Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.13ms)
node1 2023-10-12T14:27:37.185313Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.185483Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.11ms)
node1 2023-10-12T14:27:37.185524Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.185671Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.11ms)
node1 2023-10-12T14:27:37.185734Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.185883Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.12ms)
node1 2023-10-12T14:27:37.185922Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: new 1, tried 1, total 2 started
node1 2023-10-12T14:27:37.186069Z [httpworker.1] [logging/timer.h:58] [Log] [addrman] CheckAddrman: completed (0.11ms)
test 2023-10-12T14:27:37.273000Z TestFramework (ERROR): Assertion failed
Traceback (most recent call last):
File "/ci_container_base/ci/scratch/build/bitcoin-i686-pc-linux-gnu/test/functional/test_framework/test_framework.py", line 131, in main
self.run_test()
File "/ci_container_base/ci/scratch/build/bitcoin-i686-pc-linux-gnu/test/functional/rpc_net.py", line 71, in run_test
self.test_getrawaddrman()
File "/ci_container_base/ci/scratch/build/bitcoin-i686-pc-linux-gnu/test/functional/rpc_net.py", line 465, in test_getrawaddrman
check_getrawaddrman_entries(expected)
File "/ci_container_base/ci/scratch/build/bitcoin-i686-pc-linux-gnu/test/functional/rpc_net.py", line 432, in check_getrawaddrman_entries
check_addr_information(entry, expected_entry)
File "/ci_container_base/ci/scratch/build/bitcoin-i686-pc-linux-gnu/test/functional/rpc_net.py", line 411, in check_addr_information
assert_approx(result["time"], time.time(), vspan=10)
File "/ci_container_base/ci/scratch/build/bitcoin-i686-pc-linux-gnu/test/functional/test_framework/util.py", line 38, in assert_approx
raise AssertionError("%s < [%s..%s]" % (str(v), str(vexp - vspan), str(vexp + vspan)))
AssertionError: 1697120845 < [1697120847.2721245..1697120867.2721245]
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.
What's a reasonable time range for slow test runners?
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.
It seems the data is added in another test case, so I don't think an upper time can be specified, considering that it is possible that someone writes more test cases in the future and adds them in between the two test cases.
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.
I think this check should either be removed, or made an exact check (via mocktime) or some other way.
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.
ref #28671
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.
ref #28671
…n table entries 352d5eb test: getrawaddrman RPC (0xb10c) da384a2 rpc: getrawaddrman for addrman entries (0xb10c) Pull request description: Inspired by `getaddrmaninfo` (bitcoin#27511), this adds a hidden/test-only `getrawaddrman` RPC. The RPC returns information on all addresses in the address manager new and tried tables. Addrman table contents can be used in tests and during development. The RPC result encodes the `bucket` and `position`, the internal location of addresses in the tables, in the address object's string key. This allows users to choose to consume or to ignore the location information. If the internals of the address manager implementation change, the location encoding might change too. ``` getrawaddrman EXPERIMENTAL warning: this call may be changed in future releases. Returns information on all address manager entries for the new and tried tables. Result: { (json object) "table" : { (json object) buckets with addresses in the address manager table ( new, tried ) "bucket/position" : { (json object) the location in the address manager table (<bucket>/<position>) "address" : "str", (string) The address of the node "port" : n, (numeric) The port number of the node "network" : "str", (string) The network (ipv4, ipv6, onion, i2p, cjdns) of the address "services" : n, (numeric) The services offered by the node "time" : xxx, (numeric) The UNIX epoch time when the node was last seen "source" : "str", (string) The address that relayed the address to us "source_network" : "str" (string) The network (ipv4, ipv6, onion, i2p, cjdns) of the source address }, ... }, ... } Examples: > bitcoin-cli getrawaddrman > curl --user myusername --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getrawaddrman", "params": []}' -H 'content-type: text/plain;' http://127.0.0.1:8332/ ``` ACKs for top commit: willcl-ark: reACK 352d5eb amitiuttarwar: reACK 352d5eb stratospher: reACK 352d5eb. achow101: ACK 352d5eb Tree-SHA512: cc462666b5c709617c66b0e3e9a17c4c81e9e295f91bdd9572492d1cb6466fc9b6d48ee805ebe82f9f16010798370effe5c8f4db15065b8c7c0d8637675d615e
fa4c683 test: Fix failing time check in rpc_net.py (MarcoFalke) Pull request description: This check fails on slow runners, such as s390x qemu. Fix it by using mocktime. See bitcoin/bitcoin#28523 (comment) ACKs for top commit: 0xB10C: ACK fa4c683 pinheadmz: ACK fa4c683 brunoerg: crACK fa4c683 Tree-SHA512: 83fb534682e11e97537dc89de8c16f206f38af1a892a2d5970c02684c05eaea8fc9adba3159f16b2440ca0b3871d513a0562a6f3a38f19a5574a47be0919e42f
fa4c683 test: Fix failing time check in rpc_net.py (MarcoFalke) Pull request description: This check fails on slow runners, such as s390x qemu. Fix it by using mocktime. See bitcoin#28523 (comment) ACKs for top commit: 0xB10C: ACK fa4c683 pinheadmz: ACK fa4c683 brunoerg: crACK fa4c683 Tree-SHA512: 83fb534682e11e97537dc89de8c16f206f38af1a892a2d5970c02684c05eaea8fc9adba3159f16b2440ca0b3871d513a0562a6f3a38f19a5574a47be0919e42f
Inspired by
getaddrmaninfo
(#27511), this adds a hidden/test-onlygetrawaddrman
RPC. The RPC returns information on all addresses in the address manager new and tried tables. Addrman table contents can be used in tests and during development.The RPC result encodes the
bucket
andposition
, the internal location of addresses in the tables, in the address object's string key. This allows users to choose to consume or to ignore the location information. If the internals of the address manager implementation change, the location encoding might change too.