@@ -8,12 +8,13 @@ mod pub_key_request;
88mod pub_key_response;
99pub use pub_key_request:: PubKeyRequest ;
1010pub use pub_key_response:: PubKeyResponse ;
11+ use serde_json:: Value ;
1112
1213use crate :: prelude:: * ;
1314use crate :: { error:: Error , signature:: Signature } ;
1415use core:: convert:: TryFrom ;
1516use core:: { cmp:: Ordering , fmt, ops:: Deref , str:: FromStr } ;
16- use serde:: { de, ser, Deserialize , Serialize } ;
17+ use serde:: { de, ser, Deserialize , Deserializer , Serialize } ;
1718use subtle_encoding:: { base64, bech32, hex} ;
1819use tendermint_proto:: crypto:: public_key:: Sum ;
1920use tendermint_proto:: crypto:: PublicKey as RawPublicKey ;
@@ -56,6 +57,69 @@ pub enum PublicKey {
5657 Secp256k1 ( Secp256k1 ) ,
5758}
5859
60+ // Internal thunk type to facilitate deserialization from the raw Protobuf data
61+ // structure's JSON representation.
62+ #[ derive( Serialize , Deserialize ) ]
63+ struct ProtobufPublicKeyWrapper {
64+ #[ serde( rename = "Sum" ) ]
65+ sum : ProtobufPublicKey ,
66+ }
67+
68+ impl From < ProtobufPublicKeyWrapper > for PublicKey {
69+ fn from ( wrapper : ProtobufPublicKeyWrapper ) -> Self {
70+ match wrapper. sum {
71+ ProtobufPublicKey :: Ed25519 { ed25519 } => PublicKey :: Ed25519 ( ed25519) ,
72+ #[ cfg( feature = "secp256k1" ) ]
73+ ProtobufPublicKey :: Secp256k1 { secp256k1 } => PublicKey :: Secp256k1 ( secp256k1) ,
74+ }
75+ }
76+ }
77+
78+ #[ derive( Serialize , Deserialize ) ]
79+ #[ serde( tag = "type" , content = "value" ) ] // JSON custom serialization for priv_validator_key.json
80+ enum ProtobufPublicKey {
81+ #[ serde( rename = "tendermint.crypto.PublicKey_Ed25519" ) ]
82+ Ed25519 {
83+ #[ serde(
84+ serialize_with = "serialize_ed25519_base64" ,
85+ deserialize_with = "deserialize_ed25519_base64"
86+ ) ]
87+ ed25519 : Ed25519 ,
88+ } ,
89+
90+ #[ cfg( feature = "secp256k1" ) ]
91+ #[ serde( rename = "tendermint.crypto.PublicKey_Secp256K1" ) ]
92+ Secp256k1 {
93+ #[ serde(
94+ serialize_with = "serialize_secp256k1_base64" ,
95+ deserialize_with = "deserialize_secp256k1_base64"
96+ ) ]
97+ secp256k1 : Secp256k1 ,
98+ } ,
99+ }
100+
101+ /// Custom deserialization for public keys to handle multiple potential JSON
102+ /// formats from Tendermint.
103+ ///
104+ /// See <https://github.com/informalsystems/tendermint-rs/issues/1021> for
105+ /// context.
106+ // TODO(thane): Remove this once the serialization in Tendermint has been fixed.
107+ pub fn deserialize_public_key < ' de , D > ( deserializer : D ) -> Result < PublicKey , D :: Error >
108+ where
109+ D : Deserializer < ' de > ,
110+ {
111+ let v = Value :: deserialize ( deserializer) ?;
112+ if v. as_object ( )
113+ . map ( |obj| obj. contains_key ( "Sum" ) )
114+ . unwrap_or ( false )
115+ {
116+ serde_json:: from_value :: < ProtobufPublicKeyWrapper > ( v) . map ( Into :: into)
117+ } else {
118+ serde_json:: from_value :: < PublicKey > ( v)
119+ }
120+ . map_err ( serde:: de:: Error :: custom)
121+ }
122+
59123impl Protobuf < RawPublicKey > for PublicKey { }
60124
61125impl TryFrom < RawPublicKey > for PublicKey {
@@ -326,7 +390,7 @@ impl Serialize for Algorithm {
326390}
327391
328392impl < ' de > Deserialize < ' de > for Algorithm {
329- fn deserialize < D : de :: Deserializer < ' de > > ( deserializer : D ) -> Result < Self , D :: Error > {
393+ fn deserialize < D : Deserializer < ' de > > ( deserializer : D ) -> Result < Self , D :: Error > {
330394 use de:: Error ;
331395 let s = String :: deserialize ( deserializer) ?;
332396 s. parse ( ) . map_err ( D :: Error :: custom)
@@ -356,7 +420,7 @@ where
356420
357421fn deserialize_ed25519_base64 < ' de , D > ( deserializer : D ) -> Result < Ed25519 , D :: Error >
358422where
359- D : de :: Deserializer < ' de > ,
423+ D : Deserializer < ' de > ,
360424{
361425 use de:: Error ;
362426 let encoded = String :: deserialize ( deserializer) ?;
@@ -367,7 +431,7 @@ where
367431#[ cfg( feature = "secp256k1" ) ]
368432fn deserialize_secp256k1_base64 < ' de , D > ( deserializer : D ) -> Result < Secp256k1 , D :: Error >
369433where
370- D : de :: Deserializer < ' de > ,
434+ D : Deserializer < ' de > ,
371435{
372436 use de:: Error ;
373437 let encoded = String :: deserialize ( deserializer) ?;
0 commit comments