@@ -750,39 +750,124 @@ impl ZkAppAccount {
750750 }
751751}
752752
753+ /// An `AccountId` implementing `Ord` & `PartialOrd`, reproducing OCaml ordering.
754+ ///
755+ /// We compare them using `BigInteger256`, not `Fp`.
756+ /// This is a different type than `AccountId` because we want to keep the
757+ /// `BigInteger256` values around, without re-computing them every time
758+ /// `<Self as PartialOrd>::partial_cmp` is called.
759+ ///
760+ /// So far this is used only when `AccountId` are used as keys in BTreeMap, in zkapp application.
753761#[ derive( Clone , Eq ) ]
754- pub struct AccountId {
755- pub public_key : CompressedPubKey ,
756- pub token_id : TokenId ,
762+ pub struct AccountIdOrderable {
763+ // Keep the values as `BigInteger256`. This avoid re-computing them
764+ // every time `<Self as PartialOrd>::partial_cmp` is called
765+ bigint_public_key_x : BigInteger256 ,
766+ bigint_public_key_is_odd : bool ,
767+ bigint_token_id : BigInteger256 ,
768+ // We keep the original values, to convert back into `AccountId` without computing
769+ public_key : CompressedPubKey ,
770+ token_id : TokenId ,
757771}
758772
759- impl Ord for AccountId {
773+ impl PartialEq for AccountIdOrderable {
774+ fn eq ( & self , other : & Self ) -> bool {
775+ let Self {
776+ bigint_public_key_x : self_x,
777+ bigint_public_key_is_odd : self_is_odd,
778+ bigint_token_id : self_token_id,
779+ public_key : _,
780+ token_id : _,
781+ } = self ;
782+ let Self {
783+ bigint_public_key_x : other_x,
784+ bigint_public_key_is_odd : other_is_odd,
785+ bigint_token_id : other_token_id,
786+ public_key : _,
787+ token_id : _,
788+ } = other;
789+
790+ self_x == other_x && self_is_odd == other_is_odd && self_token_id == other_token_id
791+ }
792+ }
793+ impl Ord for AccountIdOrderable {
760794 fn cmp ( & self , other : & Self ) -> std:: cmp:: Ordering {
761795 self . partial_cmp ( other) . unwrap_or ( std:: cmp:: Ordering :: Equal )
762796 }
763797}
764-
765- impl PartialOrd for AccountId {
798+ impl PartialOrd for AccountIdOrderable {
799+ /// Ignore `Self::public_key` and `Self::token_id`
800+ /// We only use their bigint representations
766801 fn partial_cmp ( & self , other : & Self ) -> Option < std:: cmp:: Ordering > {
767- let self_pk: BigInteger256 = self . public_key . x . into ( ) ;
768- let other_pk: BigInteger256 = other. public_key . x . into ( ) ;
769- match self_pk. partial_cmp ( & other_pk) {
770- Some ( core:: cmp:: Ordering :: Equal ) | None => { }
802+ let Self {
803+ bigint_public_key_x : self_x,
804+ bigint_public_key_is_odd : self_is_odd,
805+ bigint_token_id : self_token_id,
806+ public_key : _,
807+ token_id : _,
808+ } = self ;
809+
810+ let Self {
811+ bigint_public_key_x : other_x,
812+ bigint_public_key_is_odd : other_is_odd,
813+ bigint_token_id : other_token_id,
814+ public_key : _,
815+ token_id : _,
816+ } = other;
817+
818+ match self_x. partial_cmp ( other_x) {
819+ None | Some ( core:: cmp:: Ordering :: Equal ) => { }
771820 ord => return ord,
772821 }
773-
774- match self . public_key . is_odd . partial_cmp ( & other. public_key . is_odd ) {
775- Some ( core:: cmp:: Ordering :: Equal ) | None => { }
822+ match self_is_odd. partial_cmp ( other_is_odd) {
823+ None | Some ( core:: cmp:: Ordering :: Equal ) => { }
776824 ord => return ord,
777825 }
826+ self_token_id. partial_cmp ( other_token_id)
827+ }
828+ }
829+
830+ impl From < AccountId > for AccountIdOrderable {
831+ fn from ( value : AccountId ) -> Self {
832+ let AccountId {
833+ public_key,
834+ token_id,
835+ } = value;
836+ let CompressedPubKey { x, is_odd } = & public_key;
837+
838+ Self {
839+ bigint_public_key_x : ( * x) . into ( ) ,
840+ bigint_public_key_is_odd : * is_odd,
841+ bigint_token_id : token_id. 0 . into ( ) ,
842+ public_key,
843+ token_id,
844+ }
845+ }
846+ }
778847
779- let self_token_id: BigInteger256 = self . token_id . 0 . into ( ) ;
780- let other_token_id: BigInteger256 = other. token_id . 0 . into ( ) ;
848+ impl From < AccountIdOrderable > for AccountId {
849+ fn from ( value : AccountIdOrderable ) -> Self {
850+ let AccountIdOrderable {
851+ bigint_public_key_x : _,
852+ bigint_public_key_is_odd : _,
853+ bigint_token_id : _,
854+ public_key,
855+ token_id,
856+ } = value;
781857
782- self_token_id. partial_cmp ( & other_token_id)
858+ Self {
859+ public_key,
860+ token_id,
861+ }
783862 }
784863}
785864
865+ #[ derive( Clone , Eq ) ]
866+ pub struct AccountId {
867+ pub public_key : CompressedPubKey ,
868+ pub token_id : TokenId ,
869+ }
870+
786871impl ToInputs for AccountId {
787872 fn to_inputs ( & self , inputs : & mut Inputs ) {
788873 let Self {
0 commit comments