-
Notifications
You must be signed in to change notification settings - Fork 208
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
fix: Add a script for fetching and flattening published capdata #5880
Conversation
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.
minimal dependencies
no kidding! An implementation of JSON in AWK. That's... hard core.
OTOH, as you say, reviewing it is kind of a pain. At least one of our customers is happy with python. I'd be OK reviewing python.
As is, I'll just say I have no objections but leave approval to @arirubinstein .
scripts/get-flattened-publication.sh
Outdated
# } | ||
# } | ||
vars="$( | ||
curl -sS "${URL_PREFIX%/}/abci_query?path=%22/custom/vstorage/data/$STORAGE_KEY%22" | \ |
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.
Incidentally, this is probably a bug somewhere in Cosmos/Tendermint. Their documentation gives example values of path
like /a/b/c
, but making a query with ?path=/a/b/c
yields a response like
{
"jsonrpc": "2.0",
"id": -1,
"error": {
"code": -32602,
"message": "Invalid params",
"data": "error converting http params to arguments: invalid character '/' looking for beginning of value"
}
}
Something is apparently JSON-decoding the parameter value rather than using it directly.
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.
Specifically https://github.com/tendermint/tendermint/blob/75d51e18f740c7cbfb7d8b4d49182ee6c7f41982/rpc/jsonrpc/server/http_uri_handler.go#L42-L51 , but I can't really get to the bottom of the reflection-heavy nonJSONStringToArg
in httpParamsToArgs
.
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.
Opened tendermint/tendermint#9164
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.
urlencode?
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.
No, I get the same results with %22
vs. "
. I even replaced an a
with \u0061
(which is a JSON escape sequence) in the quote-wrapped version and it still worked.
Was the use of https://stedolan.github.io/jq/ controversial? I see the ticket requirement,
I take that to mean that the executable we're giving them isn't complex. |
I don't think
|
Maybe we're talking about different complexity. If that jq syntax were put into a The stark difference is within |
scripts/get-flattened-publication.sh
Outdated
# Decode the value into flat JSON and insert a member for the block height. | ||
printf '%s' "${value_base64:-}" | \ | ||
base64 -d | \ | ||
awk -f "$FLATTENER" -v unwrap=value -v capdata=true | \ |
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.
For the record, if jq
is acceptable then this most complex use of awk
(unwrap, expand capdata, and then flatten) can be replaced with the following:
awk -f "$FLATTENER" -v unwrap=value -v capdata=true | \ | |
jq '[ | |
# Decode JSON in `value`, capture `slots`, then decode JSON in `body`. | |
.value | fromjson | .slots as $slots | .body | fromjson | | |
walk( | |
if type=="object" and .["@qclass"]=="bigint" then | |
# Replace bigint capdata with the sequence of digits. | |
.digits | |
elif type=="object" and .["@qclass"]=="slot" then | |
# Replace slot reference capdata with { | |
# id: <value from global `slots`>, | |
# allegedName: <extracted from local `iface`>, | |
# }. | |
{ | |
id: $slots[.index], | |
allegedName: .iface | sub("^Alleged: (?<name>.*) brand$"; "\(.name)"; "m") | |
} | |
else | |
. | |
end | |
) | | |
paths(scalars) as $path | | |
# Join deep object member names with "-". | |
{ key: $path | join("-"), value: getpath($path) } | |
] | from_entries' |
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'd approve that ;-)
if jq is acceptable
I believe it is but I defer to @arirubinstein who I think represents the customer of this script
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.
@arirubinstein @dckc @turadg Replaced the awk with jq. PTAAL.
.result.response.height? as $height | | ||
|
||
# Decode `value` as base64, then decode that as JSON. | ||
.result.response.value | @base64d | fromjson | |
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.
Today I learned that jq
can encode/decode base64: https://stedolan.github.io/jq/manual/#Formatstringsandescaping
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.
The input data is by nature a moving target, so I think it makes sense to skip tests at least until we have adopted another publication approach
Fair. I trust you've tested it with the status quo and that you'll remember to retest when the source data changes.
not sure if this code belongs in agoric-sdk or another repository such as dckc/ag-admin.
Good question. I think it's fine to include here in this misc script directory. It will also help keep the version in sync with producer logic.
|
||
if [ ":${1:-}" = '--help' -o ":$URL_PREFIX" = : -o ":$STORAGE_KEY" = : -o $# -gt 2 ]; then | ||
printf '%s' "$USAGE" | ||
exit 64 |
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.
TIL!
fi | ||
|
||
# Verify jq version. | ||
jq --version | awk ' |
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'm more familiar with version checking by grep and having the condition in shell code. nbd.
scripts/get-flattened-publication.sh
Outdated
exit; | ||
} | ||
{ | ||
print "jq version out of range (must be >=1.6 <2.0): " $0 > "/dev/stderr"; |
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.
just curious, what's required in 1.6?
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.
@base64d
, walk
, and getpath
.
# Avoid the GET interface in case interpretation of `path` as JSON is ever fixed. | ||
# https://github.com/tendermint/tendermint/issues/9164 |
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.
helpful 👍
...with minimal dependencies Fixes #5878
* Explicitly default undeclared shell variables to empty. * Allow "=" in base64 data.
66f93bc
to
21284f3
Compare
...with minimal dependencies
Fixes #5878
Description
By liberal use of
awk
(which is required in any POSIX implementation), dependencies have been reduced to hopefully-noncontroversialcurl
andbase64
.It's also possible to use with e.g.
agd
, at the cost of block height information.Security Considerations
No one should object to using the code, since it is so narrowly-scoped in both power and effects. However, auditing it is likely more difficult than would be the case if it were written in a more common language such as JS or Go (which could be done).
I'm also not sure if this code belongs in agoric-sdk or another repository such as dckc/ag-admin.
Documentation Considerations
I have tried to include sufficient examples in source code comments.
Testing Considerations
The input data is by nature a moving target, so I think it makes sense to skip tests at least until we have adopted another publication approach (cf. #5681, #5508, #5366).