@@ -442,19 +442,19 @@ func (db *merkleDB) CommitRangeProof(ctx context.Context, start, end maybe.Maybe
442442 return database .ErrClosed
443443 }
444444
445- ops := make ([]database.BatchOp , len (proof .KeyValues ))
446- keys := set.NewSet [string ](len (proof .KeyValues ))
447- for i , kv := range proof .KeyValues {
445+ ops := make ([]database.BatchOp , len (proof .KeyChanges ))
446+ keys := set.NewSet [string ](len (proof .KeyChanges ))
447+ for i , kv := range proof .KeyChanges {
448448 keys .Add (string (kv .Key ))
449449 ops [i ] = database.BatchOp {
450450 Key : kv .Key ,
451- Value : kv .Value ,
451+ Value : kv .Value . Value () ,
452452 }
453453 }
454454
455455 largestKey := end
456- if len (proof .KeyValues ) > 0 {
457- largestKey = maybe .Some (proof .KeyValues [len (proof .KeyValues )- 1 ].Key )
456+ if len (proof .KeyChanges ) > 0 {
457+ largestKey = maybe .Some (proof .KeyChanges [len (proof .KeyChanges )- 1 ].Key )
458458 }
459459 keysToDelete , err := db .getKeysNotInSet (start , largestKey , keys )
460460 if err != nil {
@@ -1094,86 +1094,66 @@ func (db *merkleDB) VerifyChangeProof(
10941094 end maybe.Maybe [[]byte ],
10951095 expectedEndRootID ids.ID ,
10961096) error {
1097- switch {
1098- case start .HasValue () && end .HasValue () && bytes .Compare (start .Value (), end .Value ()) > 0 :
1099- return ErrStartAfterEnd
1100- case proof .Empty ():
1097+ if proof == nil {
11011098 return ErrEmptyProof
1102- case end .HasValue () && len (proof .KeyChanges ) == 0 && len (proof .EndProof ) == 0 :
1103- // We requested an end proof but didn't get one.
1104- return ErrNoEndProof
1105- case start .HasValue () && len (proof .StartProof ) == 0 && len (proof .EndProof ) == 0 :
1106- // We requested a start proof but didn't get one.
1107- // Note that we also have to check that [proof.EndProof] is empty
1108- // to handle the case that the start proof is empty because all
1109- // its nodes are also in the end proof, and those nodes are omitted.
1110- return ErrNoStartProof
1111- }
1112-
1113- // Make sure the key-value pairs are sorted and in [start, end].
1114- if err := verifyKeyChanges (proof .KeyChanges , start , end ); err != nil {
1115- return err
11161099 }
11171100
1118- smallestKey := maybe .Bind (start , ToKey )
1101+ startProofKey := maybe .Bind (start , ToKey )
1102+ endProofKey := maybe .Bind (end , ToKey )
11191103
1120- // Make sure the start proof, if given, is well-formed.
1121- if err := verifyProofPath (proof .StartProof , smallestKey ); err != nil {
1122- return err
1123- }
1124-
1125- // Find the greatest key in [proof.KeyChanges]
1126- // Note that [proof.EndProof] is a proof for this key.
1127- // [largestKey] is also used when we add children of proof nodes to [trie] below.
1128- largestKey := maybe .Bind (end , ToKey )
1104+ // Update [endProofKey] with the largest key in [keyValues].
11291105 if len (proof .KeyChanges ) > 0 {
1130- // If [proof] has key-value pairs, we should insert children
1131- // greater than [end] to ancestors of the node containing [end]
1132- // so that we get the expected root ID.
1133- largestKey = maybe .Some (ToKey (proof .KeyChanges [len (proof .KeyChanges )- 1 ].Key ))
1106+ endProofKey = maybe .Some (ToKey (proof .KeyChanges [len (proof .KeyChanges )- 1 ].Key ))
11341107 }
11351108
1136- // Make sure the end proof, if given, is well-formed.
1137- if err := verifyProofPath (proof .EndProof , largestKey ); err != nil {
1109+ // Validate proof.
1110+ if err := validateChangeProof (
1111+ startProofKey ,
1112+ maybe .Bind (end , ToKey ),
1113+ proof .StartProof ,
1114+ proof .EndProof ,
1115+ proof .KeyChanges ,
1116+ endProofKey ,
1117+ db .tokenSize ,
1118+ ); err != nil {
11381119 return err
11391120 }
11401121
1141- keyValues := make (map [Key ]maybe.Maybe [[]byte ], len (proof .KeyChanges ))
1142- for _ , keyValue := range proof .KeyChanges {
1143- keyValues [ToKey (keyValue .Key )] = keyValue .Value
1144- }
1145-
1146- // want to prevent commit writes to DB, but not prevent DB reads
1122+ // Prevent commit writes to DB, but not prevent DB reads
11471123 db .commitLock .RLock ()
11481124 defer db .commitLock .RUnlock ()
11491125
11501126 if db .closed {
11511127 return database .ErrClosed
11521128 }
11531129
1154- if err := verifyAllChangeProofKeyValuesPresent (
1130+ // Ensure that the [startProof] has correct values.
1131+ if err := verifyChangeProofKeyValues (
11551132 ctx ,
11561133 db ,
1134+ proof .KeyChanges ,
11571135 proof .StartProof ,
1158- smallestKey ,
1159- largestKey ,
1160- keyValues ,
1136+ startProofKey ,
1137+ endProofKey ,
1138+ db . hasher ,
11611139 ); err != nil {
1162- return err
1140+ return fmt . Errorf ( "failed to verify start proof nodes: %w" , err )
11631141 }
11641142
1165- if err := verifyAllChangeProofKeyValuesPresent (
1143+ // Ensure that the [endProof] has correct values.
1144+ if err := verifyChangeProofKeyValues (
11661145 ctx ,
11671146 db ,
1147+ proof .KeyChanges ,
11681148 proof .EndProof ,
1169- smallestKey ,
1170- largestKey ,
1171- keyValues ,
1149+ startProofKey ,
1150+ endProofKey ,
1151+ db . hasher ,
11721152 ); err != nil {
1173- return err
1153+ return fmt . Errorf ( "failed to validate end proof nodes: %w" , err )
11741154 }
11751155
1176- // Insert the key-value pairs into the trie .
1156+ // Prepare ops for the creation of the view .
11771157 ops := make ([]database.BatchOp , len (proof .KeyChanges ))
11781158 for i , kv := range proof .KeyChanges {
11791159 ops [i ] = database.BatchOp {
@@ -1189,32 +1169,34 @@ func (db *merkleDB) VerifyChangeProof(
11891169 return err
11901170 }
11911171
1192- // For all the nodes along the edges of the proof , insert the children whose
1172+ // For all the nodes along the edges of the proofs , insert the children whose
11931173 // keys are less than [insertChildrenLessThan] or whose keys are greater
11941174 // than [insertChildrenGreaterThan] into the trie so that we get the
11951175 // expected root ID (if this proof is valid).
11961176 if err := addPathInfo (
11971177 view ,
11981178 proof .StartProof ,
1199- smallestKey ,
1200- largestKey ,
1179+ startProofKey ,
1180+ endProofKey ,
12011181 ); err != nil {
1202- return err
1182+ return fmt . Errorf ( "failed to add start proof path info: %w" , err )
12031183 }
1184+
12041185 if err := addPathInfo (
12051186 view ,
12061187 proof .EndProof ,
1207- smallestKey ,
1208- largestKey ,
1188+ startProofKey ,
1189+ endProofKey ,
12091190 ); err != nil {
1210- return err
1191+ return fmt . Errorf ( "failed to add end proof path info: %w" , err )
12111192 }
12121193
12131194 // Make sure we get the expected root.
12141195 calculatedRoot , err := view .GetMerkleRoot (ctx )
12151196 if err != nil {
12161197 return err
12171198 }
1199+
12181200 if expectedEndRootID != calculatedRoot {
12191201 return fmt .Errorf ("%w:[%s], expected:[%s]" , ErrInvalidProof , calculatedRoot , expectedEndRootID )
12201202 }
0 commit comments