Skip to content

Commit

Permalink
Update Proof and ProofOp (#206)
Browse files Browse the repository at this point in the history
* manually update Proof and introduce ProofOp to match the actual JSON encoding

* 0.33 branch seems out of date with master, committing to switch back

* Fix test

* Fix rpc endpoint test (how wasn't this detected before by the integration tests)?
  • Loading branch information
liamsi committed Apr 8, 2020
1 parent ccb7b78 commit 51934ba
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 44 deletions.
96 changes: 53 additions & 43 deletions tendermint/src/abci/proof.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,61 @@
//! ABCI Merkle proofs

use crate::error::Error;
use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
use std::{
fmt::{self, Display},
str::FromStr,
};
use subtle_encoding::{Encoding, Hex};

/// ABCI Merkle proofs
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Proof(Vec<u8>);

impl AsRef<[u8]> for Proof {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}

impl Display for Proof {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
&Hex::upper_case().encode_to_string(&self.0).unwrap()
)
}
use crate::serializers;
use serde::{Deserialize, Serialize};

/// Proof is Merkle proof defined by the list of ProofOps
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct Proof {
/// The list of ProofOps
pub ops: Vec<ProofOp>,
}

impl FromStr for Proof {
type Err = Error;

fn from_str(s: &str) -> Result<Self, Error> {
let bytes = Hex::upper_case().decode(s)?;
Ok(Proof(bytes))
}
}

impl<'de> Deserialize<'de> for Proof {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let hex = String::deserialize(deserializer)?;
Ok(Self::from_str(&hex).map_err(|e| D::Error::custom(format!("{}", e)))?)
}
/// ProofOp defines an operation used for calculating Merkle root
/// The data could be arbitrary format, providing necessary data
/// for example neighbouring node hash
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct ProofOp {
/// Type of the ProofOp
#[serde(alias = "type")]
pub field_type: String,
/// Key of the ProofOp
#[serde(
default,
serialize_with = "serializers::serialize_base64",
deserialize_with = "serializers::parse_base64"
)]
pub key: Vec<u8>,
/// Actual data
#[serde(
default,
serialize_with = "serializers::serialize_base64",
deserialize_with = "serializers::parse_base64"
)]
pub data: Vec<u8>,
}

impl Serialize for Proof {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.to_string().serialize(serializer)
#[cfg(test)]
mod test {
use super::Proof;
use crate::test::test_serialization_roundtrip;

#[test]
fn serialization_roundtrip() {
let payload = r#"
{
"ops": [
{
"type": "iavl:v",
"key": "Y29uc2Vuc3VzU3RhdGUvaWJjb25lY2xpZW50LzIy",
"data": "8QEK7gEKKAgIEAwYHCIgG9RAkJgHlxNjmyzOW6bUAidhiRSja0x6+GXCVENPG1oKKAgGEAUYFyIgwRns+dJvjf1Zk2BaFrXz8inPbvYHB7xx2HCy9ima5f8KKAgEEAMYFyogOr8EGajEV6fG5fzJ2fAAvVMgRLhdMJTzCPlogl9rxlIKKAgCEAIYFyIgcjzX/a+2bFbnNldpawQqZ+kYhIwz5r4wCUzuu1IFW04aRAoeY29uc2Vuc3VzU3RhdGUvaWJjb25lY2xpZW50LzIyEiAZ1uuG60K4NHJZZMuS9QX6o4eEhica5jIHYwflRiYkDBgX"
},
{
"type": "multistore",
"key": "aWJj",
"data": "CvEECjAKBGJhbmsSKAomCIjYAxIg2MEyyonbZButYnvSRkf2bPQg+nqA+Am1MeDxG6F4p1UKLwoDYWNjEigKJgiI2AMSIN2YHczeuXNvyetrSFQpkCcJzfB6PXVCw0i/XShMgPnIChEKB3VwZ3JhZGUSBgoECIjYAwovCgNnb3YSKAomCIjYAxIgYM0TfBli7KxhY4nWgDSDPykhUJwtKFql9RU5l86WinQKLwoDaWJjEigKJgiI2AMSIFp6aJASeInQKF8y824zjmgcFORN6M+ECbgFfJkobKs8CjAKBG1haW4SKAomCIjYAxIgsZzwmLQ7PH1UeZ/vCUSqlQmfgt3CGfoMgJLkUqKCv0EKMwoHc3Rha2luZxIoCiYIiNgDEiCiBZoBLyDGj5euy3n33ik+SpqYK9eB5xbI+iY8ycYVbwo0CghzbGFzaGluZxIoCiYIiNgDEiAJz3gEYuIhdensHU3b5qH5ons2quepd6EaRgCHXab6PQoyCgZzdXBwbHkSKAomCIjYAxIglWLA5/THPTiTxAlaLHOBYFIzEJTmKPznItUwAc8zD+AKEgoIZXZpZGVuY2USBgoECIjYAwowCgRtaW50EigKJgiI2AMSIMS8dZ1j8F6JVVv+hB1rHBZC+gIFJxHan2hM8qDC64n/CjIKBnBhcmFtcxIoCiYIiNgDEiB8VIzExUHX+SvHZFz/P9NM9THnw/gTDDLVReuZX8htLgo4CgxkaXN0cmlidXRpb24SKAomCIjYAxIg3u/Nd4L+8LT8OXJCh14o8PHIJ/GLQwsmE7KYIl1GdSYKEgoIdHJhbnNmZXISBgoECIjYAw=="
}
]
}"#;
test_serialization_roundtrip::<Proof>(payload);
}
}
15 changes: 14 additions & 1 deletion tendermint/tests/support/rpc/abci_query.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,20 @@
"response": {
"log": "exists",
"height": "1",
"proof": "010114FED0DAD959F36091AD761C922ABA3CBF1D8349990101020103011406AA2262E2F448242DF2C2607C3CDC705313EE3B0001149D16177BC71E445476174622EA559715C293740C",
"proof": {
"ops": [
{
"type": "iavl:v",
"key": "Y29uc2Vuc3VzU3RhdGUvaWJjb25lY2xpZW50LzIy",
"data": "8QEK7gEKKAgIEAwYHCIgG9RAkJgHlxNjmyzOW6bUAidhiRSja0x6+GXCVENPG1oKKAgGEAUYFyIgwRns+dJvjf1Zk2BaFrXz8inPbvYHB7xx2HCy9ima5f8KKAgEEAMYFyogOr8EGajEV6fG5fzJ2fAAvVMgRLhdMJTzCPlogl9rxlIKKAgCEAIYFyIgcjzX/a+2bFbnNldpawQqZ+kYhIwz5r4wCUzuu1IFW04aRAoeY29uc2Vuc3VzU3RhdGUvaWJjb25lY2xpZW50LzIyEiAZ1uuG60K4NHJZZMuS9QX6o4eEhica5jIHYwflRiYkDBgX"
},
{
"type": "multistore",
"key": "aWJj",
"data": "CvEECjAKBGJhbmsSKAomCIjYAxIg2MEyyonbZButYnvSRkf2bPQg+nqA+Am1MeDxG6F4p1UKLwoDYWNjEigKJgiI2AMSIN2YHczeuXNvyetrSFQpkCcJzfB6PXVCw0i/XShMgPnIChEKB3VwZ3JhZGUSBgoECIjYAwovCgNnb3YSKAomCIjYAxIgYM0TfBli7KxhY4nWgDSDPykhUJwtKFql9RU5l86WinQKLwoDaWJjEigKJgiI2AMSIFp6aJASeInQKF8y824zjmgcFORN6M+ECbgFfJkobKs8CjAKBG1haW4SKAomCIjYAxIgsZzwmLQ7PH1UeZ/vCUSqlQmfgt3CGfoMgJLkUqKCv0EKMwoHc3Rha2luZxIoCiYIiNgDEiCiBZoBLyDGj5euy3n33ik+SpqYK9eB5xbI+iY8ycYVbwo0CghzbGFzaGluZxIoCiYIiNgDEiAJz3gEYuIhdensHU3b5qH5ons2quepd6EaRgCHXab6PQoyCgZzdXBwbHkSKAomCIjYAxIglWLA5/THPTiTxAlaLHOBYFIzEJTmKPznItUwAc8zD+AKEgoIZXZpZGVuY2USBgoECIjYAwowCgRtaW50EigKJgiI2AMSIMS8dZ1j8F6JVVv+hB1rHBZC+gIFJxHan2hM8qDC64n/CjIKBnBhcmFtcxIoCiYIiNgDEiB8VIzExUHX+SvHZFz/P9NM9THnw/gTDDLVReuZX8htLgo4CgxkaXN0cmlidXRpb24SKAomCIjYAxIg3u/Nd4L+8LT8OXJCh14o8PHIJ/GLQwsmE7KYIl1GdSYKEgoIdHJhbnNmZXISBgoECIjYAw=="
}
]
},
"value": "61626364",
"key": "61626364",
"index": "-1",
Expand Down

0 comments on commit 51934ba

Please sign in to comment.