-
Notifications
You must be signed in to change notification settings - Fork 42
tendermint-rs: Fixes, cleanups, and updates #228
Conversation
- Fix --no-default-features build (and test in CI) - Eliminate most usages of (deprecated) `extern crate` - Use the `derive` cargo feature of `serde` feature instead of `serde_derive` - Rename `serializers` cargo feature of tendermint-rs to `serde` - Use 2018 edition module names (`modname.rs` instead of `modname/mod.rs`) - Update `x25519-dalek` to 0.5.2 - Update `zeroize` to 0.6
31f1be0
to
53c9931
Compare
I've been working on a This PR contains fixes for the issues I encountered. Ideally I'd like to use the crate without |
Moves the ValidatorAddr type into the Tendermint crate, as it's generally useful for any remote address. Also moves the `PeerId` type from `secret_connection` into a `node::Id` crate which isn't gated on the rest of the Secret Connection code.
53c9931
to
f9953ea
Compare
...and a `FromStr` impl. This enables parsing block heights from JSON. Right now these impls are specialized to strings (as they internally use e.g. `String::deserialize` and `String::serialize`) but in the future with the use of a custom visitor they could be extended to support both strings and numbers. Strings are immediately useful for JSONRPC.
122b5e0
to
e9ca43e
Compare
Adds a type for representing monikers
e9ca43e
to
934f7d8
Compare
Support for serializing and deserializing hash values from hex strings
Adds serde serializers/deserializers for PublicKey types which support the JSON serialization used by the JSONRPC interface.
adea22b
to
4e2af2c
Compare
Adds a type for representing IDs of Tendermint accounts, which are computed as a truncated hash of a secp256k1 public key.
This is ready for review (although I'm going to integrate this branch into my Tendermint RPC crate and make sure everything checks out there). I don't think any of these changes will impact the KMS as they all touch features of the |
} | ||
} | ||
|
||
impl From<secp256k1::PublicKey> for Id { |
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.
This implementation is copy/paste from node::Id
, but I assume account IDs/addresses work the same way? Are there test vectors I can use?
Should this be called account::Address
instead?
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.
but I assume account IDs/addresses work the same way?
Yes, the only difference is the curve (for now). secp vs ed2219
Are there test vectors I can use?
Does this work?
https://github.com/tendermint/tendermint/blob/5b8888b01b7542cd6dd856e7a322f3d4e5ccba16/crypto/secp256k1/secp256k1_test.go#L24-L30
Should this be called account::Address instead?
Good question. Tendermint doesn't have these semantics (Address is the truncated hash of whatever pubkey given, ID is only for nodes). Gaia has account addresses, but it is the bechified version: https://github.com/cosmos/cosmos-sdk/blob/9cdd1d3e9ebf5fdb72203acbaf6231c5dcde82b9/types/address.go#L73
I think it is consistent to stick with ID here.
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.
Will add that test vector to this PR, thanks!
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.
Looking at the test vectors in the address code you linked, the addr
is:
1CKZ9Nx4zgds8tU7nJHotKSDr4a9bYJCa3
I can't tell what format that is. It's mixed case so possibly Base64?
The format I'm looking at (i.e. the validator_info
object's address
field in the /status
RPC endpoint) appears to be hex, and looks like:
C73833E9BD86D34EDAD4AFD571FB5D0926294CD5
The code in this PR is fine with that format, which is what I'm immediately interested in using this for. So I guess I'll leave it as-is for now.
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 can't tell what format that is. It's mixed case so possibly Base64?
Looks like it is base58 (I should have provided the following lines for context too):
https://github.com/tendermint/tendermint/blob/5b8888b01b7542cd6dd856e7a322f3d4e5ccba16/crypto/secp256k1/secp256k1_test.go#L36
@@ -198,7 +198,7 @@ impl ConsensusMessage for Vote { | |||
|
|||
self.block_id | |||
.as_ref() | |||
.map_or(Ok(()), |bid| bid.validate_basic()) | |||
.map_or(Ok(()), ConsensusMessage::validate_basic) |
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.
clippy
prefers this (no closure, even though syntactically it's still just as cumbersome)
@@ -1,11 +1,9 @@ | |||
//! Error types | |||
|
|||
use failure::*; |
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.
This pulls in Fail
and the corresponding custom derive macro for it
use subtle_encoding::{bech32, hex}; | ||
|
||
/// Public keys allowed in Tendermint protocols | ||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] | ||
#[cfg_attr(feature = "serde", serde(tag = "type", content = "value"))] |
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.
These are configured to parse JSON in the form:
{
"type": "tendermint/PubKeyEd25519",
"value": "RblzMO4is5L1hZz6wo4kPbptzOyue6LTk4+lPhD1FRk="
}
serde( | ||
rename = "tendermint/PubKeySecp256k1", | ||
serialize_with = "serialize_secp256k1_base64", | ||
deserialize_with = "deserialize_secp256k1_base64" |
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.
Haven't tested any of this but the names appear to match what's in Tendermint
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.
But #228 (comment) means you tested this manually?
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.
Yes, also there's a unit test for parsing/serializing Ed25519 keys from JSON here:
I haven't tested anything secp256k1-related, however I'll add the account key test vectors at least. They won't exercise this, but it seems like if Ed25519 works then barring a spelling mistake above secp256k1 should work too since serde is doing the parsing and the differences are all declarative.
Using the latest commit with my Tendermint RPC crate, it's able to parse the following from the
Looks like we could probably use some custom |
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 changes look good to me! I would like to do more manual testing but this doesn't block this PR.
Thanks @tarcieri!
These comments apply to the
tendermint-rs
crate only. I've tried to avoid touching the KMS code as much as possible in this PR.--no-default-features
build (and test in CI)extern crate
syntaxderive
cargo feature ofserde
feature instead ofserde_derive
. Ditto forfailure
.serializers
cargo feature of tendermint-rs toserde
modname.rs
instead ofmodname/mod.rs
)x25519-dalek
to 0.5.2zeroize
to 0.6ValidatorAddr
=>tendermint::Address
tendermint::secret_connection::PeerId
=>tendermint::node::Id
and adds a correspondingtendermint::account::Id
Serialize
andDeserialize
for:tendermint::block::Height
,tendermint::Hash
,tendermint::PublicKey
tendermint::Moniker
type