Skip to content
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: sdk should ignore transient fields when verifying proofs #2000

Merged
merged 1 commit into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::document::document_methods::DocumentGetRawForDocumentTypeV0;
use crate::document::DocumentV0Getters;
use platform_value::Value;
use std::collections::BTreeMap;

pub trait DocumentIsEqualIgnoringTimestampsV0:
DocumentV0Getters + DocumentGetRawForDocumentTypeV0
Expand All @@ -11,10 +13,31 @@
/// created_at/updated_at
/// created_at_block_height/updated_at_block_height
/// created_at_core_block_height/updated_at_core_block_height
fn is_equal_ignoring_time_based_fields_v0(&self, rhs: &Self) -> bool {
fn is_equal_ignoring_time_based_fields_v0(
&self,
rhs: &Self,
also_ignore_fields: Option<Vec<&str>>,
) -> bool {
fn filtered_properties<'a>(
properties: &'a BTreeMap<String, Value>,
ignore_fields: &Vec<&str>,

Check warning on line 23 in packages/rs-dpp/src/document/document_methods/is_equal_ignoring_timestamps/v0/mod.rs

View workflow job for this annotation

GitHub Actions / Rust packages (dpp) / Linting

writing `&Vec` instead of `&[_]` involves a new object where a slice will do

warning: writing `&Vec` instead of `&[_]` involves a new object where a slice will do --> packages/rs-dpp/src/document/document_methods/is_equal_ignoring_timestamps/v0/mod.rs:23:28 | 23 | ignore_fields: &Vec<&str>, | ^^^^^^^^^^ help: change this to: `&[&str]` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg = note: `#[warn(clippy::ptr_arg)]` on by default
) -> BTreeMap<&'a String, &'a Value> {
properties
.iter()
.filter(|(key, _)| !ignore_fields.contains(&key.as_str()))
.collect()
}

let properties_equal = if let Some(fields) = &also_ignore_fields {
filtered_properties(self.properties(), fields)
== filtered_properties(rhs.properties(), fields)
} else {
self.properties() == rhs.properties()
};

self.id() == rhs.id()
&& self.owner_id() == rhs.owner_id()
&& self.properties() == rhs.properties()
&& properties_equal
&& self.revision() == rhs.revision()
}
}
1 change: 1 addition & 0 deletions packages/rs-dpp/src/document/document_methods/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub trait DocumentMethodsV0 {
fn is_equal_ignoring_time_based_fields(
&self,
rhs: &Self,
also_ignore_fields: Option<Vec<&str>>,
platform_version: &PlatformVersion,
) -> Result<bool, ProtocolError>;
}
4 changes: 3 additions & 1 deletion packages/rs-dpp/src/document/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ impl DocumentMethodsV0 for Document {
fn is_equal_ignoring_time_based_fields(
&self,
rhs: &Self,
also_ignore_fields: Option<Vec<&str>>,
platform_version: &PlatformVersion,
) -> Result<bool, ProtocolError> {
match (self, rhs) {
Expand All @@ -193,7 +194,8 @@ impl DocumentMethodsV0 for Document {
.document_method_versions
.is_equal_ignoring_timestamps
{
0 => Ok(document_v0.is_equal_ignoring_time_based_fields_v0(rhs_v0)),
0 => Ok(document_v0
.is_equal_ignoring_time_based_fields_v0(rhs_v0, also_ignore_fields)),
version => Err(ProtocolError::UnknownVersionMismatch {
method: "DocumentMethodV0::is_equal_ignoring_time_based_fields".to_string(),
known_versions: vec![0],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5833,10 +5833,20 @@ mod tests {
.expect("expected to get back documents")
.documents_owned();

let transient_fields = domain
.transient_fields()
.iter()
.map(|a| a.as_str())
.collect();

assert!(documents
.get(0)
.expect("expected a document")
.is_equal_ignoring_time_based_fields(&document_3, platform_version)
.is_equal_ignoring_time_based_fields(
&document_3,
Some(transient_fields),
platform_version
)
.expect("expected to run is equal"));

let drive_query = DriveDocumentQuery {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,15 @@ impl Drive {
platform_version,
)?;

let transient_fields = document_type
.transient_fields()
.iter()
.map(|a| a.as_str())
.collect();

if !document.is_equal_ignoring_time_based_fields(
&expected_document,
Some(transient_fields),
platform_version,
)? {
return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution did not contain expected document (time fields were not checked) after create with id {}", create_transition.base().id()))));
Expand All @@ -192,8 +199,15 @@ impl Drive {
platform_version,
)?;

let transient_fields = document_type
.transient_fields()
.iter()
.map(|a| a.as_str())
.collect();

if !document.is_equal_ignoring_time_based_fields(
&expected_document,
Some(transient_fields),
platform_version,
)? {
return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution did not contain expected document (time fields were not checked) after replace with id {}", replace_transition.base().id()))));
Expand Down
Loading