@@ -832,7 +832,7 @@ impl FromProof<platform::GetDataContractsRequest> for DataContracts {
832832 } ) ?;
833833
834834 verify_tenderdash_proof ( proof, mtd, & root_hash, provider) ?;
835- let maybe_contracts = contracts
835+ let contracts = contracts
836836 . into_iter ( )
837837 . map ( |( k, v) | {
838838 Identifier :: from_bytes ( & k) . map ( |id| ( id, v) ) . map_err ( |e| {
@@ -841,8 +841,13 @@ impl FromProof<platform::GetDataContractsRequest> for DataContracts {
841841 }
842842 } )
843843 } )
844- . collect :: < Result < DataContracts , Error > > ( ) ?
845- . into_option ( ) ;
844+ . collect :: < Result < DataContracts , Error > > ( ) ?;
845+
846+ let maybe_contracts = if contracts. is_empty ( ) {
847+ None
848+ } else {
849+ Some ( contracts)
850+ } ;
846851
847852 Ok ( ( maybe_contracts, mtd. clone ( ) , proof. clone ( ) ) )
848853 }
@@ -1376,8 +1381,7 @@ impl FromProof<platform::GetContestedResourcesRequest> for ContestedResources {
13761381
13771382 verify_tenderdash_proof ( proof, mtd, & root_hash, provider) ?;
13781383
1379- let resources: ContestedResources =
1380- items. into_iter ( ) . map ( |v| ContestedResource ( v) ) . collect ( ) ;
1384+ let resources: ContestedResources = items. into_iter ( ) . map ( ContestedResource ) . collect ( ) ;
13811385
13821386 Ok ( ( resources. into_option ( ) , mtd. clone ( ) , proof. clone ( ) ) )
13831387 }
@@ -1849,6 +1853,8 @@ fn u32_to_u16_opt(i: u32) -> Result<Option<u16>, Error> {
18491853pub trait Length {
18501854 /// Return number of non-None elements in the data structure
18511855 fn count_some ( & self ) -> usize ;
1856+ /// Return number of all elements in the data structure, including None
1857+ fn count ( & self ) -> usize ;
18521858}
18531859
18541860impl < T : Length > Length for Option < T > {
@@ -1858,30 +1864,52 @@ impl<T: Length> Length for Option<T> {
18581864 Some ( i) => i. count_some ( ) ,
18591865 }
18601866 }
1867+ fn count ( & self ) -> usize {
1868+ match self {
1869+ None => 0 ,
1870+ Some ( i) => i. count ( ) ,
1871+ }
1872+ }
18611873}
18621874
18631875impl < T > Length for Vec < Option < T > > {
18641876 fn count_some ( & self ) -> usize {
18651877 self . iter ( ) . filter ( |v| v. is_some ( ) ) . count ( )
18661878 }
1879+
1880+ fn count ( & self ) -> usize {
1881+ self . len ( )
1882+ }
18671883}
18681884
18691885impl < K , T > Length for Vec < ( K , Option < T > ) > {
18701886 fn count_some ( & self ) -> usize {
18711887 self . iter ( ) . filter ( |( _, v) | v. is_some ( ) ) . count ( )
18721888 }
1889+
1890+ fn count ( & self ) -> usize {
1891+ self . len ( )
1892+ }
18731893}
18741894
18751895impl < K , T > Length for BTreeMap < K , Option < T > > {
18761896 fn count_some ( & self ) -> usize {
18771897 self . values ( ) . filter ( |v| v. is_some ( ) ) . count ( )
18781898 }
1899+
1900+ fn count ( & self ) -> usize {
1901+ self . len ( )
1902+ }
18791903}
18801904
18811905impl < K , T > Length for IndexMap < K , Option < T > > {
18821906 fn count_some ( & self ) -> usize {
18831907 self . values ( ) . filter ( |v| v. is_some ( ) ) . count ( )
18841908 }
1909+
1910+ fn count ( & self ) -> usize {
1911+ self . len ( )
1912+ }
18851913}
18861914
18871915/// Implement Length trait for a type
@@ -1891,16 +1919,24 @@ impl<K, T> Length for IndexMap<K, Option<T>> {
18911919/// * `$object`: The type for which to implement Length trait
18921920/// * `$len`: A closure that returns the length of the object; if ommitted, defaults to 1
18931921macro_rules! define_length {
1894- ( $object: ty, $len : expr) => {
1922+ ( $object: ty, $some : expr , $counter : expr) => {
18951923 impl Length for $object {
18961924 fn count_some( & self ) -> usize {
18971925 #[ allow( clippy:: redundant_closure_call) ]
1898- $len( self )
1926+ $some( self )
1927+ }
1928+
1929+ fn count( & self ) -> usize {
1930+ #[ allow( clippy:: redundant_closure_call) ]
1931+ $counter( self )
18991932 }
19001933 }
19011934 } ;
1935+ ( $object: ty, $some: expr) => {
1936+ define_length!( $object, $some, $some) ;
1937+ } ;
19021938 ( $object: ty) => {
1903- define_length!( $object, |_| 1 ) ;
1939+ define_length!( $object, |_| 1 , |_| 1 ) ;
19041940 } ;
19051941}
19061942
@@ -1910,22 +1946,30 @@ define_length!(Document);
19101946define_length ! ( Identity ) ;
19111947define_length ! ( IdentityBalance ) ;
19121948define_length ! ( IdentityBalanceAndRevision ) ;
1913- define_length ! ( IdentitiesContractKeys , |x: & IdentitiesContractKeys | x
1914- . values( )
1915- . map( |v| v. count_some( ) )
1916- . sum( ) ) ;
1949+ define_length ! (
1950+ IdentitiesContractKeys ,
1951+ |x: & IdentitiesContractKeys | x. values( ) . map( |v| v. count_some( ) ) . sum( ) ,
1952+ |x: & IdentitiesContractKeys | x. len( )
1953+ ) ;
19171954define_length ! ( ContestedResources , |x: & ContestedResources | x. 0 . len( ) ) ;
19181955define_length ! ( Contenders , |x: & Contenders | x. contenders. len( ) ) ;
19191956define_length ! ( Voters , |x: & Voters | x. 0 . len( ) ) ;
19201957define_length ! (
19211958 VotePollsGroupedByTimestamp ,
1922- |x: & VotePollsGroupedByTimestamp | x. 0 . iter( ) . map( |v| v. 1 . len( ) ) . sum( )
1959+ |x: & VotePollsGroupedByTimestamp | x. 0 . iter( ) . map( |v| v. 1 . len( ) ) . sum( ) ,
1960+ |x: & VotePollsGroupedByTimestamp | x. 0 . len( )
19231961) ;
1962+
1963+ /// Convert a type into an Option
19241964trait IntoOption
19251965where
19261966 Self : Sized ,
19271967{
1928- /// For zero-length data structures, return None, otherwise return Some(self)
1968+ /// For zero-length data structures, return None, otherwise return Some(self).
1969+ ///
1970+ /// In case of a zero-length data structure, the function returns None.
1971+ /// Otherwise, it returns Some(self), even it all values are None. This is to ensure that proof of absence
1972+ /// preserves the keys that are not present in the data structure.
19291973 fn into_option ( self ) -> Option < Self > ;
19301974}
19311975
@@ -1934,7 +1978,7 @@ impl<L: Length> IntoOption for L {
19341978 where
19351979 Self : Sized ,
19361980 {
1937- if self . count_some ( ) == 0 {
1981+ if self . count ( ) == 0 {
19381982 None
19391983 } else {
19401984 Some ( self )
0 commit comments